diff --git a/CHANGE.LOG.md b/CHANGE.LOG.md deleted file mode 100644 index e9480e5..0000000 --- a/CHANGE.LOG.md +++ /dev/null @@ -1,116 +0,0 @@ -# Atto Emacs Change Log - -## Atto v1.20 30 Mar 2018 -* very small enhancement to previous fix. When we go to the end of the file we do not reframe if the end of file is already displayed in the window. - -## Atto v1.19 9 Mar 2018 -* fixed issue with display reframe when last line is displayed and text has been cut above it. On scrolling to end of buffer there was a nasty jump to frame the screen with the last line anchored to the end of the screen. This issue was present in the original Anthonys Editor. - -## Atto v1.18 1 Feb 2018 -* fixed bug with opening file ~/.xxx where filename completion has not been used. If ~ is detected we force a call as if the user had selected filename completion. - -## Atto v1.17 20 Jan 2018 -* fixed bug with lnend() when at end of buffer, fixed killtoeol() behaviour - -## Atto V1.16 25 Nov 2017 -* merged in file descriptor leak from and code reductions in complete.c from "The Infinnovation team" -* small changes in complete.c to reduce line count - -## Atto v1.15.1 25 Nov 2017 -* small code optimisation to reduce line count - -## Atto v1.15 29 July 2017 -* Merged in fixes for multi-byte/wide chars, backspace and cursor position provided by Matt Fielding (Magnetic Realms) -* Added simplified chinese test file to docs - -## Atto v1.14 14 April 2017 -* added alternative home and end key bindings (some systems differ in setup) -* removed some non emacs bindings -* re-order definition of keys - -## Atto v1.13 13 April 2017 -* fixed problem with set_parse_state. To be sure of setting hilite state we parse the text up to point at the top of the screen. -* fixed problem with complete.c not initialising response buffer -* added resize-terminal - -## Atto v1.12 12 April 2017 -* added UTF8 support - -## Atto v1.11 11 April 2017 -* reduced some functions to 1 liners in command.c to make space for future UTF8 fixes - -## Atto v1.10 9 March 2017 -* discard unbound keystrokes, compacted 1 line functions in command.c - -## Atto v1.9 9 March 2017 -* Fixed cut, copy code to avoid corruption as pointer p should be set after call to movegap() - -## Atto v1.8 22 December 2016 -* Added generic syntax highlighting, removed the basic undo command to keep code cound under 2000 lines. -* made searchtext start from empty string (as per GNU emacs) -* modified search_forward() and search_backwards() so that they can be called on any buffer (not just current buf) -* fixed failed search when first char in buffer should match. -* some comments reduced to 1 line to save precious line count -* added flag to getinput() to clear the response if required - -## Atto v1.7, 12 October 2016 -* Added filename completion -NOTE: If this creates a problem on windows the change can be backed out by uncommenting the line in command.c readfile() and using the getinput() instead of getfilename() functions. - -## Atto v1.6, 29 December 2015 -* Fixed display problem when editing same buffer in multiple windows. -* Fixed overflow of filename variable when a large filename is supplied at the command line -* Reformatted comments at top of source files to claw back 30 more lines for defect fixes - -## Atto v1.5, 20 December 2015 -* Added INS = toggle-overwrite-mode -* flushed keyboard on detection of Esc in search and replace, which means if you touch the arrow keys you exit cleanly without writing the rest of an escape sequence into the buffer. -* Added entries for escape key binding (eg esc-v and esc-V) to handle when CAPSLOCK is active. -* Handled CAPSLOCK when prompted y/n to exit. -* Line count is 1987. - -## Atto v1.4.3, 15 December 2015 -* fixed bug with display of last line - -## Atto v1.4.2, 13 December 2015 -* Fixed crash bug with free_windows on MS windows, thanks to Ed Davies for reporting -* went through all files and ensure correct indentation and tabstops, ensured if (foo) { opening brace style -* line count is 1955 - -## Atto v1.4.1, 12 December 2015 -* Added esc-@ as alternative to C-space for set-mark - -## Atto v1.4 8 December 2015 -* Working Atto that supports multiple windows. It all fits in 1969 lines of C ! -* Fixed bug that meant that scrolling to end of file in other than the first window jumped off the screen. -* Removed previous-buffer which was not going to get used. -* Removed redundant definitions of FIRST_LINE -* Corrected PgDn and PgUp to work with variable size windows. - -## Atto V1.3.1 5 December 2015 -* Fixed bug with count_buffers causing kill-buffer to core dump - -## Atto V1.3 1 December 2015 -* Added M-r search and replace -* Added M-g goto-line -* Updated show-pos with line/total_lines count -* fixed bug introduced in 1.2 where last modified buffer would not trigger the prompt to save. -* code footprint is 1775 lines ! - -## Atto v1.2 29 November 2015 -* Implemented multibuffer support, added approx 180 lines of code -* First buffer created is called *scatch* -* Creates *scratch* buffer if you want to delete last buffer -* Added C-x C-n next-buffer -* Added C-x C-p prev-buffer -* Added C-x k delete-buffer -* Consumed key.h into header.h -* code footprint is 1586 lines ! - -## Atto v1.1 26 November 2015 -* Reduced code footprint by simplification of key code and the definition of keymap. This means I dont have to edit more than one map to add a function. -* Added forward and reverse text search. -* Code footprint is less than 1400 lines ! - -## Atto v1.0 2015 - diff --git a/README.md b/README.md index f8ada7e..3fb6f79 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # kg Emacs -A small functional Emacs in Go +A small functional Emacs written in Go -kg Emacs is inspired by Atto Emacs (by Hugh Barney), MicroEmacs, Nano, Pico and his earlier project known as Perfect Emacs [1]. +kg Emacs is inspired by Atto Emacs (by Hugh Barney), MicroEmacs, Nano, Pico and his earlier project known as Perfect Emacs [1]. Also by JOE, uEmacs, MicroEmacs, mg, zile and of course, GNU Emacs. I learnt Emacs on a Sun 2/120 a long time ago in a galaxy far, far, away. > A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away. @@ -13,9 +13,12 @@ kg Emacs is inspired by Atto Emacs (by Hugh Barney), MicroEmacs, Nano, Pico and ## Goals of kg Emacs -* Mine own, finally. +* Mine own, finally, in Go. +* uses an array of Rune to handle Unicode codepoints. * no damn Overwrite mode. Too bad. * pure Go implementation +* removal of the C-based hilite stuff +* add go routines for some operations. * ... * Be easy to understand without extensive study (to encourage further experimentation). @@ -24,7 +27,7 @@ Using Atto as the lowest functional Emacs, Hugh had to consider the essential fe ## Derivation -kg is based on the design of Atto Emacs which is based on the public domain code of Anthony Howe's editor (commonly known as Anthony's Editor or AE, [2]). Rather than representing a file as a linked list of lines, the AE Editor uses the concept of a Buffer-Gap [4,5,6]. A Buffer-Gap editor stores the file in a single piece of contiguous memory with some extra unused space known as the buffer gap. On character insertion and deletion the gap is first moved to the current point. A character deletion then extends the gap by moving the gap pointer back by 1 OR the gap is reduced by 1 when a character is inserted. The Buffer-Gap technique is elegant and significantly reduces the amount of code required to load a file, modify it and redraw the display. The proof of this is seen when you consider that Atto supports almost the same command set that Pico supports, but Pico requires almost 17 times the amount of code. +kg is based on the design of _Atto Emacs which is based on the public domain code of Anthony Howe's editor (commonly known as Anthony's Editor or AE, [2]). Rather than representing a file as a linked list of lines, the AE Editor uses the concept of a Buffer-Gap [4,5,6]. A Buffer-Gap editor stores the file in a single piece of contiguous memory with some extra unused space known as the buffer gap. On character insertion and deletion the gap is first moved to the current point. A character deletion then extends the gap by moving the gap pointer back by 1 OR the gap is reduced by 1 when a character is inserted. The Buffer-Gap technique is elegant and significantly reduces the amount of code required to load a file, modify it and redraw the display. The proof of this is seen when you consider that Atto supports almost the same command set that Pico supports, but Pico requires almost 17 times the amount of code._ ## Comparisons with Other Emacs Implementations @@ -155,7 +158,7 @@ Maybe a piece-table or piece-chain implementation? Maybe a different key mapping ## Multiple Windows or Not? -Kg supports multiple windows +Kg supports multiple windows. ## Known Issues @@ -181,5 +184,5 @@ Kg supports multiple windows [3] MG - https://github.com/rzalamena/mg [4] Jonathan Payne, Buffer-Gap: http://ned.rubyforge.org/doc/buffer-gap.txt [5] Anthony Howe, http://ned.rubyforge.org/doc/editor-101.txt - [6] Anthony Howe, http://ned.rubyforge.org/doc/editor-102.txt + [6] Hugh Barney, https://github.com/hughbarney/atto diff --git a/ToDo.md b/ToDo.md index e1777ce..25c17f8 100644 --- a/ToDo.md +++ b/ToDo.md @@ -1,3 +1,9 @@ # To Do +* screen down and up TBD +* word movement (who does that) is TBD * mouse to change windows (only works with one-window) +* the CollapseGap idea needs to be optimized, too sloppy rght now +* make editing larger files faster by optimizing the Buffer stuff +* the error(s) from RuneAt which are currently panic-ing on check, should be handled differently +* and what's with func window2Buffer(w *Window) (window.go); needs the multiwindow update unfangled. \ No newline at end of file diff --git a/buffer.go b/buffer.go index 9f90928..a2ba767 100644 --- a/buffer.go +++ b/buffer.go @@ -5,25 +5,30 @@ import ( "fmt" ) +/* + * Buffer is where all the opertions on the main rune array are implemented. + * Because of the Gap, all the indexing around it should be done by these routines. + */ + // Buffer main struct type Buffer struct { - data []rune - preLen int - postLen int - Next *Buffer /* b_next Link to next buffer_t */ - Mark int /* b_mark the mark */ - OrigPoint int /* b_cpoint the original current point, used for mutliple window displaying */ - PageStart int /* b_page start of page */ - PageEnd int /* b_epage end of page */ - Reframe bool /* b_reframe force a reframe of the display */ - WinCount int /* b_cnt count of windows referencing this buffer */ - TextSize int /* b_size current size of text being edited (not including gap) */ - PrevSize int /* b_psize previous size */ - PointRow int /* b_row Point row */ - PointCol int /* b_col Point col */ - Filename string // b_fname[NAME_MAX + 1]; /* filename */ - Buffername string //[b_bnameSTRBUF_S]; /* buffer name */ - Flags byte /* char b_flags buffer flags */ + data []rune + preLen int + postLen int + Next *Buffer /* b_next Link to next buffer_t */ + Mark int /* b_mark the mark */ + OrigPoint int /* b_cpoint the original current point, used for mutliple window displaying */ + PageStart int /* b_page start of page */ + PageEnd int /* b_epage end of page */ + Reframe bool /* b_reframe force a reframe of the display */ + WinCount int /* b_cnt count of windows referencing this buffer */ + TextSize int /* b_size current size of text being edited (not including gap) */ + PrevSize int /* b_psize previous size */ + PointRow int /* b_row Point row */ + PointCol int /* b_col Point col */ + Filename string // b_fname[NAME_MAX + 1]; /* filename */ + Buffername string //[b_bnameSTRBUF_S]; /* buffer name */ + Flags byte /* char b_flags buffer flags */ modified bool } @@ -35,34 +40,27 @@ func (bp *Buffer) MarkModified() { // NewBuffer - Create a new Buffer func NewBuffer() *Buffer { nb := Buffer{} - nb.data = []rune("\n") - nb.preLen = 0 - nb.postLen = len(nb.data) + nb.setText("\n") return &nb } -// SetText xxx -func (bp *Buffer) SetText(s string) { +// setText xxx +func (bp *Buffer) setText(s string) { bp.data = []rune(s) bp.preLen = 0 bp.postLen = len(bp.data) } -// GetText xxx -func (bp *Buffer) GetText() string { +// getText xxx +func (bp *Buffer) getText() string { ret := make([]rune, bp.preLen+bp.postLen) copy(ret, bp.data) copy(ret[bp.preLen:], bp.data[bp.postStart():]) return string(ret) } -func (bp *Buffer) logBufferEOB(pt int) { - -} - // RuneAt finally reliable!! func (bp *Buffer) RuneAt(pt int) (rune, error) { - bp.logBufferEOB(pt) if pt >= len(bp.data) { return 0, errors.New("Beyond data buffer in RuneAt") } @@ -88,10 +86,6 @@ func (bp *Buffer) dataPointForBufferPoint(pt int) int { // AddRune add a run to the buffer func (bp *Buffer) AddRune(ch rune) { - // if bp.data == nil { - // bp.SetText(string(ch)) - // return - // } if bp.gapLen() == 0 { _ = bp.GrowGap(gapchunk) } @@ -107,7 +101,6 @@ func (bp *Buffer) Point() int { // SetPoint set the current point to np func (bp *Buffer) SetPoint(np int) { - bp.logBufferEOB(np) bp.CollapseGap() // move gap <-(left) by np chars gs := bp.gapStart() @@ -117,17 +110,10 @@ func (bp *Buffer) SetPoint(np int) { bp.postLen++ } if bp.PageEnd < bp.preLen { - //// log.Println("reframing!") bp.Reframe = true } } -//SetPointAndCursor xxx -func (bp *Buffer) SetPointAndCursor(np int) { - bp.SetPoint(np) - bp.setCursor() -} - // setCursor xxx func (bp *Buffer) setCursor() { x, y := bp.XYForPoint(bp.preLen) @@ -184,11 +170,10 @@ func (bp *Buffer) Insert(s string) { bp.MarkModified() } -// GetTextForLines return string for [l1, l2) (l2 not included) -func (bp *Buffer) GetTextForLines(l1, l2 int) string { +// getTextForLines return string for [l1, l2) (l2 not included) +func (bp *Buffer) getTextForLines(l1, l2 int) string { pt1 := bp.PointForLine(l1) pt2 := bp.PointForLine(l2) - //fmt.Println(pt1, pt2) ret := make([]rune, pt2-pt1) j := 0 for i := pt1; j < len(ret); i++ { @@ -479,7 +464,8 @@ func (bp *Buffer) PointUp() { if npt < bp.PageStart { bp.Reframe = true } - bp.SetPointAndCursor(npt) + bp.SetPoint(npt) + bp.setCursor() } // PointDown move point down one line @@ -495,7 +481,8 @@ func (bp *Buffer) PointDown() { if npt > bp.PageEnd { bp.Reframe = true } - bp.SetPointAndCursor(npt) + bp.SetPoint(npt) + bp.setCursor() } // PointNext move point left one @@ -518,8 +505,6 @@ func (bp *Buffer) PointPrevious() { bp.data[bp.postStart()-1] = bp.data[bp.preLen-1] bp.preLen-- bp.postLen++ - //bp.setCursor() - bp.logBufferEOB(bp.preLen) } // UpUp Move up one screen line @@ -536,7 +521,6 @@ func (bp *Buffer) UpUp(pt, cc int) int { // DownDown Move down one screen line func (bp *Buffer) DownDown(pt, cc int) int { - //bp := e.CurrentBuffer return bp.SegNext(bp.LineStart(pt), pt, cc) } @@ -548,7 +532,7 @@ func (bp *Buffer) GetLineStats() (curline int, lastline int) { return curline, lastline } -// DebugPrint xxx +// DebugPrint prints out a view of the buffer and the gap and so on. func (bp *Buffer) DebugPrint() { fmt.Printf("*********(gap)\n") for i := 0; i < len(bp.data); i++ { diff --git a/buffer_test.go b/buffer_test.go index d95e42b..e58af3d 100644 --- a/buffer_test.go +++ b/buffer_test.go @@ -22,15 +22,12 @@ func TestBufferGrow(t *testing.T) { r := "[Ut enim ad minima]" //u := "[veniam, quis nostrum exercitationem]" //w := "Οὐχὶ ταὐτὰ παρίσταταί \nμοι γιγνώσκειν, ὦ ἄνδρες\n" - gb.PrintPoint() - gb.SetText(s) + gb.setText(s) for i := 0; i < 11; i++ { gb.PointNext() } - gb.PrintPoint() gb.Insert(r) - gb.PrintPoint() - fmt.Printf("|%v|\n", gb.GetText()) + fmt.Printf("|%v|\n", gb.getText()) } func TestAddRune2(t *testing.T) { @@ -39,7 +36,7 @@ func TestAddRune2(t *testing.T) { // 012345678 91123 4567892 123456789 3123456 s := "Lorem\nlite\nsed ut\naliqua. \nhhh" // 01234 56789 1123456 789212345 67893 - gb.SetText(s) + gb.setText(s) gb.DebugPrint() //gb.Insert("foo") gb.AddRune('f') @@ -57,7 +54,7 @@ func TestCollapseGap(t *testing.T) { // 012345678 91123 4567892 123456789 3123456 s := "Lorem\nlite\nsed ut\naliqua. \nhhh" // 01234 56789 1123456 789212345 67893 - gb.SetText(s) + gb.setText(s) gb.DebugPrint() //gb.Insert("foo") gb.AddRune('f') @@ -77,16 +74,16 @@ func TestTextLines(t *testing.T) { gb := NewBuffer() s := "Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit,\nsed do eiusmod tempor incididunt ut\nlabore et dolore magna aliqua. " // 0123456789112345678921234567 89312345678941234567895123456 7896123456789612345678971234567898123456789 - gb.SetText(s) - //fmt.Printf("%v\n", gb.GetText()) + gb.setText(s) + //fmt.Printf("%v\n", gb.getText()) fmt.Println("--- [1, 3)") - fmt.Printf("%v\n", gb.GetTextForLines(1, 3)) + fmt.Printf("%v\n", gb.getTextForLines(1, 3)) fmt.Println("--- [1, 2)") - fmt.Printf("%v\n", gb.GetTextForLines(1, 2)) + fmt.Printf("%v\n", gb.getTextForLines(1, 2)) fmt.Println("--- [2, 3)") - fmt.Printf("%v\n", gb.GetTextForLines(2, 3)) + fmt.Printf("%v\n", gb.getTextForLines(2, 3)) fmt.Println("--- [2, 5)") - fmt.Printf("%v\n", gb.GetTextForLines(2, 5)) + fmt.Printf("%v\n", gb.getTextForLines(2, 5)) gb.DebugPrint() t.Error("force print") } @@ -95,7 +92,7 @@ func TestLineStart(t *testing.T) { gb := NewBuffer() s := "Lorem\nlite\nsed ut\naliqua.-\nhhh" // 01234 56789 1123456 789212345 67893 - gb.SetText(s) + gb.setText(s) // gb.Insert("foo") // gb.AddRune('k') // gb.AddRune('r') @@ -124,7 +121,7 @@ func TestLineStart2(t *testing.T) { // 012345678 91123 4567892 123456789 3123456 //s := "fooLorem\nlite\nsed ut\naliqua.-\nhhh" // 012345678 91123 4567892 123456789 3123456 - gb.SetText(s) + gb.setText(s) //gb.Insert("foo") gb.AddRune('f') gb.AddRune('o') @@ -161,7 +158,7 @@ func TestLineForPoint(t *testing.T) { // 012345 67891 1234567 892123456 7893123456 //s := "fooLorem\nlite\nsed ut\naliqua.-\nhhh" // 012345678 91123 4567892 123456789 3123456 - gb.SetText(s) + gb.setText(s) //gb.Insert("foo") // gb.AddRune('f') // gb.AddRune('o') @@ -201,7 +198,7 @@ func TestLineForPoint2(t *testing.T) { // 111111111 22222 3333333 444444444 555 //s := "fooLorem\nlite\nsed ut\naliqua.-\nhhh" // 012345678 91123 4567892 123456789 3123456 - gb.SetText(s) + gb.setText(s) gb.Insert("foo") // gb.AddRune('f') // gb.AddRune('o') @@ -241,7 +238,7 @@ func TestLineEnd(t *testing.T) { // 01234 56789 1123456 789212345 67893 //s := "fookris\nLorem\nlite\nsed ut\naliqua. \nhhh" // 01234567 891123 45678 9212345 678931234 56789412345 - gb.SetText(s) + gb.setText(s) gb.Insert("foo") gb.AddRune('k') gb.AddRune('r') @@ -262,7 +259,7 @@ func TestLineLenAtPoint(t *testing.T) { gb := NewBuffer() s := "Lorem\nlite\nsed ut\naliqua.-\nhhh" // 01234 56789 1123456 789212345 67893 - gb.SetText(s) + gb.setText(s) // gb.Insert("foo") // gb.AddRune('k') // gb.AddRune('r') @@ -294,7 +291,7 @@ func TestLineLenAtPoint2(t *testing.T) { // 01234 56789 1123456 789212345 67893 //s := "fookris\nLorem\nlite\nsed ut\naliqua. \nhhh" // 01234567 891123 45678 9212345 678931234 56789412345 - gb.SetText(s) + gb.setText(s) gb.Insert("foo") gb.AddRune('k') gb.AddRune('r') @@ -332,9 +329,9 @@ func TestPointForLine(t *testing.T) { // 01234 56789 1123456 789212345 67893 //s := "fookris\nLorem\nlite\nsed ut\naliqua. \nhhh" // 01234567 891123 45678 9212345 678931234 56789412345 - gb.SetText(s) + gb.setText(s) gb.DebugPrint() - // gb.SetText(s) + // gb.setText(s) // gb.Insert("foo") // gb.AddRune('k') // gb.AddRune('r') @@ -357,8 +354,8 @@ func TestPointForLine2(t *testing.T) { // 01234 56789 1123456 789212345 67893 //s := "fookris\nLorem\nlite\nsed ut\naliqua. \nhhh" // 01234567 891123 45678 9212345 678931234 56789412345 - gb.SetText(s) - // gb.SetText(s) + gb.setText(s) + // gb.setText(s) gb.Insert("foo") gb.AddRune('k') gb.AddRune('r') @@ -380,8 +377,8 @@ func TestColumnForPoint(t *testing.T) { // 01234 56789 1123456 789212345 67893 //s := "fookris\nLorem\nlite\nsed ut\naliqua. \nhhh" // 01234567 891123 45678 9212345 678931234 56789412345 - gb.SetText(s) - gb.SetText(s) + gb.setText(s) + gb.setText(s) gb.Insert("foo") gb.AddRune('k') gb.AddRune('r') @@ -414,7 +411,7 @@ func TestPointForXY(t *testing.T) { // 01234 56789 1123456 789212345 67893 //s := "fookris\nLorem\nlite\nsed ut\naliqua. \nhhh" // 01234567 891123 45678 9212345 678931234 56789412345 - gb.SetText(s) + gb.setText(s) gb.Insert("foo") gb.AddRune('k') gb.AddRune('r') @@ -447,7 +444,7 @@ func TestXYForPoint(t *testing.T) { // 01234 56789 1123456 789212345 67893 //s := "fookris\nLorem\nlite\nsed ut\naliqua. \nhhh" // 01234567 891123 45678 9212345 678931234 56789412345 - gb.SetText(s) + gb.setText(s) gb.Insert("foo") gb.AddRune('k') gb.AddRune('r') @@ -522,7 +519,7 @@ func TestSetPoint(t *testing.T) { // 01234 56789 1123456 789212345 67893 //s := "fookris\nLXorem\nlite\nsed ut\naliqua. \nhhh" // 01234567 8911234 5678 9212345 678931234 56789412345 - gb.SetText(s) + gb.setText(s) gb.DebugPrint() gb.Insert("foo") gb.AddRune('k') @@ -565,7 +562,7 @@ func TestSetPoint(t *testing.T) { func TestRuneAt(t *testing.T) { gb := NewBuffer() s := "Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit,\nsed do eiusmod tempor incididunt ut\nlabore et dolore magna aliqua. " - gb.SetText(s) + gb.setText(s) gb.Insert("foo") gb.AddRune('k') gb.AddRune('r') @@ -601,8 +598,8 @@ func TestSegStart(t *testing.T) { // 01234 56789 1123456 789212345 67893 //s := "fookris\nLorem\nlite\nsed ut\naliqua. \nhhh" // 01234567 891123 45678 9212345 678931234 56789412345 - gb.SetText(s) - gb.SetText(s) + gb.setText(s) + gb.setText(s) gb.Insert("foo") gb.AddRune('k') gb.AddRune('r') @@ -629,8 +626,8 @@ func TestSegNext(t *testing.T) { // 01234 56789 1123456 789212345 67893 //s := "fookris\nLorem\nlite\nsed ut\naliqua. \nhhh" // 01234567 891123 45678 9212345 678931234 56789412345 - gb.SetText(s) - gb.SetText(s) + gb.setText(s) + gb.setText(s) gb.Insert("foo") gb.AddRune('k') gb.AddRune('r') @@ -657,8 +654,8 @@ func TestUpUp(t *testing.T) { // 01234 56789 1123456 789212345 67893 //s := "fookris\nLorem\nlite\nsed ut\naliqua. \nhhh" // 01234567 891123 45678 9212345 678931234 56789412345 - gb.SetText(s) - gb.SetText(s) + gb.setText(s) + gb.setText(s) gb.Insert("foo") gb.AddRune('k') gb.AddRune('r') @@ -685,8 +682,8 @@ func TestDownDown(t *testing.T) { // 01234 56789 1123456 789212345 67893 //s := "fookris\nLorem\nlite\nsed ut\naliqua. \nhhh" // 01234567 891123 45678 9212345 678931234 56789412345 - gb.SetText(s) - gb.SetText(s) + gb.setText(s) + gb.setText(s) gb.Insert("foo") gb.AddRune('k') gb.AddRune('r') diff --git a/ccode/buffer.c b/ccode/buffer.c deleted file mode 100644 index 0166af7..0000000 --- a/ccode/buffer.c +++ /dev/null @@ -1,127 +0,0 @@ -/* buffer.c, Atto Emacs, Hugh Barney, Public Domain, 2015 */ - -#include -#include -#include "header.h" - -void buffer_init(buffer_t *bp) -{ - bp->b_mark = NOMARK; - bp->b_point = 0; - bp->b_cpoint = 0; - bp->b_page = 0; - bp->b_epage = 0; - bp->b_reframe = 0; - bp->b_size = 0; - bp->b_psize = 0; - bp->b_flags = 0; - bp->b_cnt = 0; - bp->b_buf = NULL; - bp->b_ebuf = NULL; - bp->b_gap = NULL; - bp->b_egap = NULL; - bp->b_next = NULL; - bp->b_fname[0] = '\0'; -} - -/* Find a buffer by filename or create if requested */ -buffer_t* find_buffer (char *fname, int cflag) -{ - buffer_t *bp = NULL; - buffer_t *sb = NULL; - - bp = bheadp; - while (bp != NULL) { - if (strcmp (fname, bp->b_fname) == 0 || strcmp(fname, bp->b_bname) == 0) { - return (bp); - } - bp = bp->b_next; - } - - if (cflag != FALSE) { - if ((bp = (buffer_t *) malloc (sizeof (buffer_t))) == NULL) - return (0); - - buffer_init(bp); - assert(bp != NULL); - - /* find the place in the list to insert this buffer */ - if (bheadp == NULL) { - bheadp = bp; - } else if (strcmp (bheadp->b_fname, fname) > 0) { - /* insert at the begining */ - bp->b_next = bheadp; - bheadp = bp; - } else { - for (sb = bheadp; sb->b_next != NULL; sb = sb->b_next) - if (strcmp (sb->b_next->b_fname, fname) > 0) - break; - - /* and insert it */ - bp->b_next = sb->b_next; - sb->b_next = bp; - } - } - return bp; -} - -/* unlink from the list of buffers, free associated memory, assumes buffer has been saved if modified */ -int delete_buffer (buffer_t *bp) -{ - buffer_t *sb = NULL; - - /* we must have switched to a different buffer first */ - assert(bp != curbp); - - /* if buffer is the head buffer */ - if (bp == bheadp) { - bheadp = bp->b_next; - } else { - /* find place where the bp buffer is next */ - for (sb = bheadp; sb->b_next != bp && sb->b_next != NULL; sb = sb->b_next) - ; - assert(sb->b_next == bp || sb->b_next == NULL); - sb->b_next = bp->b_next; - } - - /* now we can delete */ - free(bp->b_buf); - free(bp); - return TRUE; -} - -void next_buffer() -{ - assert(curbp != NULL); - assert(bheadp != NULL); - disassociate_b(curwp); - curbp = (curbp->b_next != NULL ? curbp->b_next : bheadp); - associate_b2w(curbp,curwp); -} - -char* get_buffer_name(buffer_t *bp) -{ - return (strlen(bp->b_fname) > 0) ? bp->b_fname : bp->b_bname; -} - -int count_buffers() -{ - buffer_t* bp; - int i; - - for (i=0, bp=bheadp; bp != NULL; bp = bp->b_next) - i++; - - return i; -} - -int modified_buffers() -{ - buffer_t* bp; - - for (bp=bheadp; bp != NULL; bp = bp->b_next) - if (bp->b_flags & B_MODIFIED) - return TRUE; - - return FALSE; -} diff --git a/ccode/command.c b/ccode/command.c deleted file mode 100644 index f277ef1..0000000 --- a/ccode/command.c +++ /dev/null @@ -1,354 +0,0 @@ -/* command.c, Atto Emacs, Public Domain, Hugh Barney, 2016, Derived from: Anthony's Editor January 93 */ - -#include "header.h" - -void quit() { done = 1; } -void up() { curbp->b_point = lncolumn(curbp, upup(curbp, curbp->b_point),curbp->b_col); } -void down() { curbp->b_point = lncolumn(curbp, dndn(curbp, curbp->b_point),curbp->b_col); } -void lnbegin() { curbp->b_point = segstart(curbp, lnstart(curbp,curbp->b_point), curbp->b_point); } -void version() { msg(VERSION); } -void top() { curbp->b_point = 0; } -void bottom() { curbp->b_point = pos(curbp, curbp->b_ebuf); if (curbp->b_epage < pos(curbp, curbp->b_ebuf)) curbp->b_reframe = 1;} -void block() { curbp->b_mark = curbp->b_point; } -void copy() { copy_cut(FALSE); } -void cut() { copy_cut(TRUE); } -void resize_terminal() { one_window(curwp); } - -void quit_ask() -{ - if (modified_buffers() > 0) { - mvaddstr(MSGLINE, 0, "Modified buffers exist; really exit (y/n) ?"); - clrtoeol(); - if (!yesno(FALSE)) - return; - } - quit(); -} - -/* flag = default answer, FALSE=n, TRUE=y */ -int yesno(int flag) -{ - int ch; - - addstr(flag ? " y\b" : " n\b"); - refresh(); - ch = getch(); - if (ch == '\r' || ch == '\n') - return (flag); - return (tolower(ch) == 'y'); -} - -void redraw() -{ - window_t *wp; - - clear(); - for (wp=wheadp; wp != NULL; wp = wp->w_next) - wp->w_update = TRUE; - update_display(); -} - -void left() -{ - int n = prev_utf8_char_size(); - while (0 < curbp->b_point && n-- > 0) - --curbp->b_point; -} - -void right() -{ - int n = utf8_size(*ptr(curbp,curbp->b_point)); - while ((curbp->b_point < pos(curbp, curbp->b_ebuf)) && n-- > 0) - ++curbp->b_point; -} - -/* work out number of bytes based on first byte */ -int utf8_size(char_t c) -{ - if (c >= 192 && c < 224) return 2; - if (c >= 224 && c < 240) return 3; - if (c >= 240 && c < 248) return 4; - return 1; /* if in doubt it is 1 */ -} - -int prev_utf8_char_size() -{ - int n; - for (n=2;n<5;n++) - if (-1 < curbp->b_point - n && (utf8_size(*(ptr(curbp, curbp->b_point - n))) == n)) - return n; - return 1; -} - -void lnend() -{ - if (curbp->b_point == pos(curbp, curbp->b_ebuf)) return; /* do nothing if EOF */ - curbp->b_point = dndn(curbp, curbp->b_point); - point_t p = curbp->b_point; - left(); - curbp->b_point = (*ptr(curbp, curbp->b_point) == '\n') ? curbp->b_point : p; -} - -void wleft() -{ - char_t *p; - while (!isspace(*(p = ptr(curbp, curbp->b_point))) && curbp->b_buf < p) - --curbp->b_point; - while (isspace(*(p = ptr(curbp, curbp->b_point))) && curbp->b_buf < p) - --curbp->b_point; -} - -void pgdown() -{ - curbp->b_page = curbp->b_point = upup(curbp, curbp->b_epage); - while (0 < curbp->b_row--) - down(); - curbp->b_epage = pos(curbp, curbp->b_ebuf); -} - -void pgup() -{ - int i = curwp->w_rows; - while (0 < --i) { - curbp->b_page = upup(curbp, curbp->b_page); - up(); - } -} - -void wright() -{ - char_t *p; - while (!isspace(*(p = ptr(curbp, curbp->b_point))) && p < curbp->b_ebuf) - ++curbp->b_point; - while (isspace(*(p = ptr(curbp, curbp->b_point))) && p < curbp->b_ebuf) - ++curbp->b_point; -} - -void insert() -{ - assert(curbp->b_gap <= curbp->b_egap); - if (curbp->b_gap == curbp->b_egap && !growgap(curbp, CHUNK)) - return; - curbp->b_point = movegap(curbp, curbp->b_point); - - /* overwrite if mid line, not EOL or EOF, CR will insert as normal */ - if ((curbp->b_flags & B_OVERWRITE) && *input != '\r' && *(ptr(curbp, curbp->b_point)) != '\n' && curbp->b_point < pos(curbp,curbp->b_ebuf) ) { - *(ptr(curbp, curbp->b_point)) = *input; - if (curbp->b_point < pos(curbp, curbp->b_ebuf)) - ++curbp->b_point; - } else { - *curbp->b_gap++ = *input == '\r' ? '\n' : *input; - curbp->b_point = pos(curbp, curbp->b_egap); - } - curbp->b_flags |= B_MODIFIED; -} - -void backsp() -{ - curbp->b_point = movegap(curbp, curbp->b_point); - if (curbp->b_buf < curbp->b_gap) { - curbp->b_gap -= prev_utf8_char_size(); - curbp->b_flags |= B_MODIFIED; - } - curbp->b_point = pos(curbp, curbp->b_egap); -} - -void delete() -{ - curbp->b_point = movegap(curbp, curbp->b_point); - if (curbp->b_egap < curbp->b_ebuf) { - curbp->b_egap += utf8_size(*curbp->b_egap); - curbp->b_point = pos(curbp, curbp->b_egap); - curbp->b_flags |= B_MODIFIED; - } -} - -void gotoline() -{ - int line; - point_t p; - - if (getinput("Goto line: ", temp, STRBUF_S, F_CLEAR)) { - line = atoi(temp); - p = line_to_point(line); - if (p != -1) { - curbp->b_point = p; - msg("Line %d", line); - } else { - msg("Line %d, not found", line); - } - } -} - -void insertfile() -{ - if (getfilename("Insert file: ", temp, NAME_MAX)) - (void)insert_file(temp, TRUE); -} - -void readfile() -{ - buffer_t *bp; - - temp[0] = '\0'; - int result = getfilename("Find file: ", (char*)temp, NAME_MAX); - /* int result = getinput("Find file: ", (char*)temp, NAME_MAX, F_CLEAR); */ - - if (result) { - bp = find_buffer(temp, TRUE); - disassociate_b(curwp); /* we are leaving the old buffer for a new one */ - curbp = bp; - associate_b2w(curbp, curwp); - - /* load the file if not already loaded */ - if (bp != NULL && bp->b_fname[0] == '\0') { - if (!load_file(temp)) { - msg("New file %s", temp); - } - strncpy(curbp->b_fname, temp, NAME_MAX); - curbp->b_fname[NAME_MAX] = '\0'; /* truncate if required */ - } - } -} - -void savebuffer() -{ - if (curbp->b_fname[0] != '\0') { - save(curbp->b_fname); - return; - } else { - writefile(); - } - refresh(); -} - -void writefile() -{ - strncpy(temp, curbp->b_fname, NAME_MAX); - if (getinput("Write file: ", temp, NAME_MAX, F_NONE)) - if (save(temp) == TRUE) - strncpy(curbp->b_fname, temp, NAME_MAX); -} - -void killbuffer() -{ - buffer_t *kill_bp = curbp; - buffer_t *bp; - int bcount = count_buffers(); - - /* do nothing if only buffer left is the scratch buffer */ - if (bcount == 1 && 0 == strcmp(get_buffer_name(curbp), "*scratch*")) - return; - - if (curbp->b_flags & B_MODIFIED) { - mvaddstr(MSGLINE, 0, "Discard changes (y/n) ?"); - clrtoeol(); - if (!yesno(FALSE)) - return; - } - - if (bcount == 1) { - /* create a scratch buffer */ - bp = find_buffer("*scratch*", TRUE); - strcpy(bp->b_bname, "*scratch*"); - } - - next_buffer(); - assert(kill_bp != curbp); - delete_buffer(kill_bp); -} - -void iblock() -{ - block(); - msg("Mark set"); -} - -void toggle_overwrite_mode() { - if (curbp->b_flags & B_OVERWRITE) - curbp->b_flags &= ~B_OVERWRITE; - else - curbp->b_flags |= B_OVERWRITE; -} - -void killtoeol() -{ - if (curbp->b_point == pos(curbp, curbp->b_ebuf)) - return; /* do nothing if at end of file */ - if (*(ptr(curbp, curbp->b_point)) == 0xa) { - delete(); /* delete CR if at start of empty line */ - } else { - curbp->b_mark = curbp->b_point; - lnend(); - if (curbp->b_mark != curbp->b_point) copy_cut(TRUE); - } -} - -void copy_cut(int cut) -{ - char_t *p; - /* if no mark or point == marker, nothing doing */ - if (curbp->b_mark == NOMARK || curbp->b_point == curbp->b_mark) - return; - if (scrap != NULL) { - free(scrap); - scrap = NULL; - } - if (curbp->b_point < curbp->b_mark) { - /* point above marker: move gap under point, region = marker - point */ - (void) movegap(curbp, curbp->b_point); - p = ptr(curbp, curbp->b_point); - nscrap = curbp->b_mark - curbp->b_point; - } else { - /* if point below marker: move gap under marker, region = point - marker */ - (void) movegap(curbp, curbp->b_mark); - p = ptr(curbp, curbp->b_mark); - nscrap = curbp->b_point - curbp->b_mark; - } - if ((scrap = (char_t*) malloc(nscrap)) == NULL) { - msg("No more memory available."); - } else { - (void) memcpy(scrap, p, nscrap * sizeof (char_t)); - if (cut) { - curbp->b_egap += nscrap; /* if cut expand gap down */ - curbp->b_point = pos(curbp, curbp->b_egap); /* set point to after region */ - curbp->b_flags |= B_MODIFIED; - msg("%ld bytes cut.", nscrap); - } else { - msg("%ld bytes copied.", nscrap); - } - curbp->b_mark = NOMARK; /* unmark */ - } -} - -void paste() -{ - if(curbp->b_flags & B_OVERWRITE) - return; - if (nscrap <= 0) { - msg("Scrap is empty. Nothing to paste."); - } else if (nscrap < curbp->b_egap - curbp->b_gap || growgap(curbp, nscrap)) { - curbp->b_point = movegap(curbp, curbp->b_point); - memcpy(curbp->b_gap, scrap, nscrap * sizeof (char_t)); - curbp->b_gap += nscrap; - curbp->b_point = pos(curbp, curbp->b_egap); - curbp->b_flags |= B_MODIFIED; - } -} - -void showpos() -{ - int current, lastln; - point_t end_p = pos(curbp, curbp->b_ebuf); - - get_line_stats(¤t, &lastln); - - if (curbp->b_point == end_p) { - msg("[EOB] Line = %d/%d Point = %d/%d", current, lastln, - curbp->b_point, ((curbp->b_ebuf - curbp->b_buf) - (curbp->b_egap - curbp->b_gap))); - } else { - msg("Char = %s 0x%x Line = %d/%d Point = %d/%d", unctrl(*(ptr(curbp, curbp->b_point))), *(ptr(curbp, curbp->b_point)), - current, lastln, - curbp->b_point, ((curbp->b_ebuf - curbp->b_buf) - (curbp->b_egap - curbp->b_gap))); - } -} diff --git a/ccode/complete.c b/ccode/complete.c deleted file mode 100644 index 708e7b9..0000000 --- a/ccode/complete.c +++ /dev/null @@ -1,85 +0,0 @@ -/* complete.c, Atto Emacs, Hugh Barney, Public Domain, 2016 */ - -#include "header.h" - -/* basic filename completion, based on code in uemacs/PK */ -int getfilename(char *prompt, char *buf, int nbuf) -{ - static char temp_file[] = TEMPFILE; - int cpos = 0; /* current character position in string */ - int k = 0, c, fd, didtry, iswild = 0; - - char sys_command[255]; - FILE *fp = NULL; - buf[0] ='\0'; - - for (;;) { - didtry = (k == 0x09); /* Was last command tab-completion? */ - display_prompt_and_response(prompt, buf); - k = getch(); /* get a character from the user */ - - switch(k) { - case 0x0a: /* cr, lf */ - case 0x0d: - if (cpos > 0 && NULL != strchr(buf, '~')) goto do_tab; - case 0x07: /* ctrl-g, abort */ - if (fp != NULL) fclose(fp); - return (k != 0x07 && cpos > 0); - - case 0x7f: /* del, erase */ - case 0x08: /* backspace */ - if (cpos == 0) continue; - buf[--cpos] = '\0'; - break; - - case 0x15: /* C-u kill */ - cpos = 0; - buf[0] = '\0'; - break; - -do_tab: - case 0x09: /* TAB, complete file name */ - /* scan backwards for a wild card and set */ - iswild=0; - while (cpos > 0) { - cpos--; - if (buf[cpos] == '*' || buf[cpos] == '?') - iswild = 1; - } - - /* first time retrieval */ - if (! didtry) { - if (fp != NULL) fclose(fp); - strcpy(temp_file, TEMPFILE); - if (-1 == (fd = mkstemp(temp_file))) - fatal("%s: Failed to create temp file\n"); - strcpy(sys_command, "echo "); - strcat(sys_command, buf); - if (!iswild) strcat(sys_command, "*"); - strcat(sys_command, " >"); - strcat(sys_command, temp_file); - strcat(sys_command, " 2>&1"); - (void) ! system(sys_command); /* stop compiler unused result warning */ - fp = fdopen(fd, "r"); - unlink(temp_file); - } - - /* copy next filename into buf */ - while ((c = getc(fp)) != EOF && c != '\n' && c != ' ') - if (cpos < nbuf - 1 && c != '*') - buf[cpos++] = c; - - buf[cpos] = '\0'; - if (c != ' ') rewind(fp); - didtry = 1; - break; - - default: - if (cpos < nbuf - 1) { - buf[cpos++] = k; - buf[cpos] = '\0'; - } - break; - } - } -} diff --git a/ccode/display.c b/ccode/display.c deleted file mode 100644 index 74a9220..0000000 --- a/ccode/display.c +++ /dev/null @@ -1,284 +0,0 @@ -/* display.c, Atto Emacs, Public Domain, Hugh Barney, 2016, Derived from: Anthony's Editor January 93 */ - -#include "header.h" - -/* Reverse scan for start of logical line containing offset */ -point_t lnstart(buffer_t *bp, register point_t off) -{ - register char_t *p; - do - p = ptr(bp, --off); - while (bp->b_buf < p && *p != '\n'); - return (bp->b_buf < p ? ++off : 0); -} - -/* Forward scan for start of logical line segment (corresponds to screen line) containing 'finish' */ -point_t segstart(buffer_t *bp, point_t start, point_t finish) -{ - char_t *p; - int c = 0; - point_t scan = start; - - while (scan < finish) { - p = ptr(bp, scan); - if (*p == '\n') { - c = 0; - start = scan + 1; - } else if (COLS <= c) { - c = 0; - start = scan; - } - scan += utf8_size(*ptr(bp,scan)); - c += *p == '\t' ? 8 - (c & 7) : 1; - } - return (c < COLS ? start : finish); -} - -/* Forward scan for start of logical line segment following 'finish' */ -point_t segnext(buffer_t *bp, point_t start, point_t finish) -{ - char_t *p; - int c = 0; - - point_t scan = segstart(bp, start, finish); - for (;;) { - p = ptr(bp, scan); - if (bp->b_ebuf <= p || COLS <= c) - break; - scan += utf8_size(*ptr(bp,scan)); - if (*p == '\n') - break; - c += *p == '\t' ? 8 - (c & 7) : 1; - } - return (p < bp->b_ebuf ? scan : pos(bp, bp->b_ebuf)); -} - -/* Move up one screen line */ -point_t upup(buffer_t *bp, point_t off) -{ - point_t curr = lnstart(bp, off); - point_t seg = segstart(bp, curr, off); - if (curr < seg) - off = segstart(bp, curr, seg-1); - else - off = segstart(bp, lnstart(bp,curr-1), curr-1); - return (off); -} - -/* Move down one screen line */ -point_t dndn(buffer_t *bp, point_t off) -{ - return (segnext(bp, lnstart(bp,off), off)); -} - -/* Return the offset of a column on the specified line */ -point_t lncolumn(buffer_t *bp, point_t offset, int column) -{ - int c = 0; - char_t *p; - while ((p = ptr(bp, offset)) < bp->b_ebuf && *p != '\n' && c < column) { - c += *p == '\t' ? 8 - (c & 7) : 1; - offset += utf8_size(*ptr(bp,offset)); - } - return (offset); -} - -void display(window_t *wp, int flag) -{ - char_t *p; - int i, j, k, nch; - buffer_t *bp = wp->w_bufp; - int token_type = ID_DEFAULT; - - /* find start of screen, handle scroll up off page or top of file */ - /* point is always within b_page and b_epage */ - if (bp->b_point < bp->b_page) - bp->b_page = segstart(bp, lnstart(bp,bp->b_point), bp->b_point); - - /* reframe when scrolled off bottom */ - if (bp->b_reframe == 1 || (bp->b_epage <= bp->b_point && curbp->b_point != pos(curbp, curbp->b_ebuf))) { - bp->b_reframe = 0; - /* Find end of screen plus one. */ - bp->b_page = dndn(bp, bp->b_point); - /* if we scoll to EOF we show 1 blank line at bottom of screen */ - if (pos(bp, bp->b_ebuf) <= bp->b_page) { - bp->b_page = pos(bp, bp->b_ebuf); - i = wp->w_rows - 1; - } else { - i = wp->w_rows - 0; - } - /* Scan backwards the required number of lines. */ - while (0 < i--) - bp->b_page = upup(bp, bp->b_page); - } - - move(wp->w_top, 0); /* start from top of window */ - i = wp->w_top; - j = 0; - bp->b_epage = bp->b_page; - set_parse_state(bp, bp->b_epage); /* are we in a multline comment ? */ - - /* paint screen from top of page until we hit maxline */ - while (1) { - /* reached point - store the cursor position */ - if (bp->b_point == bp->b_epage) { - bp->b_row = i; - bp->b_col = j; - } - p = ptr(bp, bp->b_epage); - nch = 1; - if (wp->w_top + wp->w_rows <= i || bp->b_ebuf <= p) /* maxline */ - break; - if (*p != '\r') { - nch = utf8_size(*p); - if ( nch > 1) { - wchar_t c; - /* reset if invalid multi-byte character */ - if (mbtowc(&c, (char*)p, 6) < 0) mbtowc(NULL, NULL, 0); - j += wcwidth(c) < 0 ? 1 : wcwidth(c); - display_utf8(bp, *p, nch); - } else if (isprint(*p) || *p == '\t' || *p == '\n') { - j += *p == '\t' ? 8-(j&7) : 1; - token_type = parse_text(bp, bp->b_epage); - attron(COLOR_PAIR(token_type)); - addch(*p); - } else { - const char *ctrl = unctrl(*p); - j += (int) strlen(ctrl); - addstr(ctrl); - } - } - if (*p == '\n' || COLS <= j) { - j -= COLS; - if (j < 0) - j = 0; - ++i; - } - bp->b_epage = bp->b_epage + nch; - } - - /* replacement for clrtobot() to bottom of window */ - for (k=i; k < wp->w_top + wp->w_rows; k++) { - move(k, j); /* clear from very last char not start of line */ - clrtoeol(); - j = 0; /* thereafter start of line */ - } - - b2w(wp); /* save buffer stuff on window */ - modeline(wp); - if (wp == curwp && flag) { - dispmsg(); - move(bp->b_row, bp->b_col); /* set cursor */ - refresh(); - } - wp->w_update = FALSE; -} - -void display_utf8(buffer_t *bp, char_t c, int n) -{ - char sbuf[6]; - int i = 0; - - for (i=0; ib_epage + i); - sbuf[n] = '\0'; - addstr(sbuf); -} - -void modeline(window_t *wp) -{ - int i; - char lch, mch, och; - - standout(); - move(wp->w_top + wp->w_rows, 0); - lch = (wp == curwp ? '=' : '-'); - mch = ((wp->w_bufp->b_flags & B_MODIFIED) ? '*' : lch); - och = ((wp->w_bufp->b_flags & B_OVERWRITE) ? 'O' : lch); - - sprintf(temp, "%c%c%c Atto: %c%c %s", lch,och,mch,lch,lch, get_buffer_name(wp->w_bufp)); - addstr(temp); - - for (i = strlen(temp) + 1; i <= COLS; i++) - addch(lch); - standend(); -} - -void dispmsg() -{ - move(MSGLINE, 0); - if (msgflag) { - addstr(msgline); - msgflag = FALSE; - } - clrtoeol(); -} - -void display_prompt_and_response(char *prompt, char *response) -{ - mvaddstr(MSGLINE, 0, prompt); - /* if we have a value print it and go to end of it */ - if (response[0] != '\0') - addstr(response); - clrtoeol(); -} - -void update_display() -{ - window_t *wp; - buffer_t *bp; - - bp = curwp->w_bufp; - bp->b_cpoint = bp->b_point; /* cpoint only ever set here */ - - /* only one window */ - if (wheadp->w_next == NULL) { - display(curwp, TRUE); - refresh(); - bp->b_psize = bp->b_size; - return; - } - - display(curwp, FALSE); /* this is key, we must call our win first to get accurate page and epage etc */ - - /* never curwp, but same buffer in different window or update flag set*/ - for (wp=wheadp; wp != NULL; wp = wp->w_next) { - if (wp != curwp && (wp->w_bufp == bp || wp->w_update)) { - w2b(wp); - display(wp, FALSE); - } - } - - /* now display our window and buffer */ - w2b(curwp); - dispmsg(); - move(curwp->w_row, curwp->w_col); /* set cursor for curwp */ - refresh(); - bp->b_psize = bp->b_size; /* now safe to save previous size for next time */ -} - -void w2b(window_t *w) -{ - w->w_bufp->b_point = w->w_point; - w->w_bufp->b_page = w->w_page; - w->w_bufp->b_epage = w->w_epage; - w->w_bufp->b_row = w->w_row; - w->w_bufp->b_col = w->w_col; - - /* fixup pointers in other windows of the same buffer, if size of edit text changed */ - if (w->w_bufp->b_point > w->w_bufp->b_cpoint) { - w->w_bufp->b_point += (w->w_bufp->b_size - w->w_bufp->b_psize); - w->w_bufp->b_page += (w->w_bufp->b_size - w->w_bufp->b_psize); - w->w_bufp->b_epage += (w->w_bufp->b_size - w->w_bufp->b_psize); - } -} - -void b2w(window_t *w) -{ - w->w_point = w->w_bufp->b_point; - w->w_page = w->w_bufp->b_page; - w->w_epage = w->w_bufp->b_epage; - w->w_row = w->w_bufp->b_row; - w->w_col = w->w_bufp->b_col; - w->w_bufp->b_size = (w->w_bufp->b_ebuf - w->w_bufp->b_buf) - (w->w_bufp->b_egap - w->w_bufp->b_gap); -} diff --git a/ccode/gap.c b/ccode/gap.c deleted file mode 100644 index c17b055..0000000 --- a/ccode/gap.c +++ /dev/null @@ -1,210 +0,0 @@ -/* gap.c, Atto Emacs, Public Domain, Hugh Barney, 2016, Derived from: Anthony's Editor January 93 */ - -#include -#include "header.h" - -/* Enlarge gap by n chars, position of gap cannot change */ -int growgap(buffer_t *bp, point_t n) -{ - char_t *new; - point_t buflen, newlen, xgap, xegap; - - assert(bp->b_buf <= bp->b_gap); - assert(bp->b_gap <= bp->b_egap); - assert(bp->b_egap <= bp->b_ebuf); - - xgap = bp->b_gap - bp->b_buf; - xegap = bp->b_egap - bp->b_buf; - buflen = bp->b_ebuf - bp->b_buf; - - /* reduce number of reallocs by growing by a minimum amount */ - n = (n < MIN_GAP_EXPAND ? MIN_GAP_EXPAND : n); - newlen = buflen + n * sizeof (char_t); - - if (buflen == 0) { - if (newlen < 0 || MAX_SIZE_T < newlen) - fatal("%s: Failed to allocate required memory.\n"); - new = (char_t*) malloc((size_t) newlen); - if (new == NULL) - fatal("%s: Failed to allocate required memory.\n"); /* Cannot edit a file without a buffer. */ - } else { - if (newlen < 0 || MAX_SIZE_T < newlen) { - msg("Failed to allocate required memory"); - return (FALSE); - } - new = (char_t*) realloc(bp->b_buf, (size_t) newlen); - if (new == NULL) { - msg("Failed to allocate required memory"); /* Report non-fatal error. */ - return (FALSE); - } - } - - /* Relocate pointers in new buffer and append the new - * extension to the end of the gap. - */ - bp->b_buf = new; - bp->b_gap = bp->b_buf + xgap; - bp->b_ebuf = bp->b_buf + buflen; - bp->b_egap = bp->b_buf + newlen; - while (xegap < buflen--) - *--bp->b_egap = *--bp->b_ebuf; - bp->b_ebuf = bp->b_buf + newlen; - - assert(bp->b_buf < bp->b_ebuf); /* Buffer must exist. */ - assert(bp->b_buf <= bp->b_gap); - assert(bp->b_gap < bp->b_egap); /* Gap must grow only. */ - assert(bp->b_egap <= bp->b_ebuf); - return (TRUE); -} - -point_t movegap(buffer_t *bp, point_t offset) -{ - char_t *p = ptr(bp, offset); - while (p < bp->b_gap) - *--bp->b_egap = *--bp->b_gap; - while (bp->b_egap < p) - *bp->b_gap++ = *bp->b_egap++; - assert(bp->b_gap <= bp->b_egap); - assert(bp->b_buf <= bp->b_gap); - assert(bp->b_egap <= bp->b_ebuf); - return (pos(bp, bp->b_egap)); -} - -/* Given a buffer offset, convert it to a pointer into the buffer */ -char_t * ptr(buffer_t *bp, register point_t offset) -{ - if (offset < 0) - return (bp->b_buf); - return (bp->b_buf+offset + (bp->b_buf + offset < bp->b_gap ? 0 : bp->b_egap-bp->b_gap)); -} - -/* Given a pointer into the buffer, convert it to a buffer offset */ -point_t pos(buffer_t *bp, register char_t *cp) -{ - assert(bp->b_buf <= cp && cp <= bp->b_ebuf); - return (cp - bp->b_buf - (cp < bp->b_egap ? 0 : bp->b_egap - bp->b_gap)); -} - -int posix_file(char *fn) -{ - if (fn[0] == '_') - return (FALSE); - - for (; *fn != '\0'; ++fn) { - if (!isalnum(*fn) && *fn != '.' && *fn != '_' && *fn != '-' && *fn != '/') - return (FALSE); - } - return (TRUE); -} - -int save(char *fn) -{ - FILE *fp; - point_t length; - - if (!posix_file(fn)) { - msg("Not a portable POSIX file name."); - return (FALSE); - } - fp = fopen(fn, "w"); - if (fp == NULL) { - msg("Failed to open file \"%s\".", fn); - return (FALSE); - } - (void) movegap(curbp, (point_t) 0); - length = (point_t) (curbp->b_ebuf - curbp->b_egap); - if (fwrite(curbp->b_egap, sizeof (char), (size_t) length, fp) != length) { - msg("Failed to write file \"%s\".", fn); - return (FALSE); - } - if (fclose(fp) != 0) { - msg("Failed to close file \"%s\".", fn); - return (FALSE); - } - curbp->b_flags &= ~B_MODIFIED; - msg("File \"%s\" %ld bytes saved.", fn, pos(curbp, curbp->b_ebuf)); - return (TRUE); -} - -int load_file(char *fn) -{ - /* reset the gap, make it the whole buffer */ - curbp->b_gap = curbp->b_buf; - curbp->b_egap = curbp->b_ebuf; - top(); - return insert_file(fn, FALSE); -} - -/* reads file into buffer at point */ -int insert_file(char *fn, int modflag) -{ - FILE *fp; - size_t len; - struct stat sb; - - if (stat(fn, &sb) < 0) { - msg("Failed to find file \"%s\".", fn); - return (FALSE); - } - if (MAX_SIZE_T < sb.st_size) { - msg("File \"%s\" is too big to load.", fn); - return (FALSE); - } - if (curbp->b_egap - curbp->b_gap < sb.st_size * sizeof (char_t) && !growgap(curbp, sb.st_size)) - return (FALSE); - if ((fp = fopen(fn, "r")) == NULL) { - msg("Failed to open file \"%s\".", fn); - return (FALSE); - } - curbp->b_point = movegap(curbp, curbp->b_point); - curbp->b_gap += len = fread(curbp->b_gap, sizeof (char), (size_t) sb.st_size, fp); - - if (fclose(fp) != 0) { - msg("Failed to close file \"%s\".", fn); - return (FALSE); - } - curbp->b_flags &= (modflag ? B_MODIFIED : ~B_MODIFIED); - msg("File \"%s\" %ld bytes read.", fn, len); - return (TRUE); -} - -/* find the point for start of line ln */ -point_t line_to_point(int ln) -{ - point_t end_p = pos(curbp, curbp->b_ebuf); - point_t p, start; - - for (p=0, start=0; p < end_p; p++) { - if ( *(ptr(curbp, p)) == '\n') { - if (--ln == 0) - return start; - if (p + 1 < end_p) - start = p + 1; - } - } - return -1; -} - -/* scan buffer and fill in curline and lastline */ -void get_line_stats(int *curline, int *lastline) -{ - point_t end_p = pos(curbp, curbp->b_ebuf); - point_t p; - int line; - - *curline = -1; - - for (p=0, line=0; p < end_p; p++) { - line += (*(ptr(curbp,p)) == '\n') ? 1 : 0; - *lastline = line; - - if (*curline == -1 && p == curbp->b_point) { - *curline = (*(ptr(curbp,p)) == '\n') ? line : line + 1; - } - } - - *lastline = *lastline + 1; - - if (curbp->b_point == end_p) - *curline = *lastline; -} diff --git a/ccode/header.h b/ccode/header.h deleted file mode 100644 index d6a1249..0000000 --- a/ccode/header.h +++ /dev/null @@ -1,208 +0,0 @@ -/* header.h, Atto Emacs, Public Domain, Hugh Barney, 2016, Derived from: Anthony's Editor January 93 */ -#define _XOPEN_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -int mkstemp(char *); - -#define VERSION "Atto 1.20, Public Domain, Mar 2018, by Hugh Barney, No warranty." -#define PROG_NAME "atto" -#define B_MODIFIED 0x01 /* modified buffer */ -#define B_OVERWRITE 0x02 /* overwite mode */ -#define MSGLINE (LINES-1) -#define NOMARK -1 -#define CHUNK 8096L -#define K_BUFFER_LENGTH 256 -#define TEMPBUF 512 -#define STRBUF_L 256 -#define STRBUF_M 64 -#define STRBUF_S 16 -#define MIN_GAP_EXPAND 512 -#define TEMPFILE "/tmp/feXXXXXX" -#define F_NONE 0 -#define F_CLEAR 1 -#define ID_DEFAULT 1 -#define ID_SYMBOL 2 -#define ID_MODELINE 3 -#define ID_DIGITS 4 -#define ID_LINE_COMMENT 5 -#define ID_BLOCK_COMMENT 6 -#define ID_DOUBLE_STRING 7 -#define ID_SINGLE_STRING 8 - -typedef unsigned char char_t; -typedef long point_t; - -typedef struct keymap_t { - char *key_desc; /* name of bound function */ - char *key_bytes; /* the string of bytes when this key is pressed */ - void (*func)(void); -} keymap_t; - -typedef struct buffer_t -{ - struct buffer_t *b_next; /* Link to next buffer_t */ - point_t b_mark; /* the mark */ - point_t b_point; /* the point */ - point_t b_cpoint; /* the original current point, used for mutliple window displaying */ - point_t b_page; /* start of page */ - point_t b_epage; /* end of page */ - point_t b_reframe; /* force a reframe of the display */ - int b_cnt; /* count of windows referencing this buffer */ - int b_size; /* current size of text being edited (not including gap) */ - int b_psize; /* previous size */ - char_t *b_buf; /* start of buffer */ - char_t *b_ebuf; /* end of buffer */ - char_t *b_gap; /* start of gap */ - char_t *b_egap; /* end of gap */ - int b_row; /* cursor row */ - int b_col; /* cursor col */ - char b_fname[NAME_MAX + 1]; /* filename */ - char b_bname[STRBUF_S]; /* buffer name */ - char b_flags; /* buffer flags */ -} buffer_t; - -typedef struct window_t -{ - struct window_t *w_next; /* Next window */ - struct buffer_t *w_bufp; /* Buffer displayed in window */ - point_t w_point; - point_t w_mark; - point_t w_page; - point_t w_epage; - char w_top; /* Origin 0 top row of window */ - char w_rows; /* no. of rows of text in window */ - int w_row; /* cursor row */ - int w_col; /* cursor col */ - int w_update; - char w_name[STRBUF_S]; -} window_t; - -extern buffer_t *curbp; /* current buffer */ -extern buffer_t *bheadp; /* head of list of buffers */ -extern window_t *curwp; -extern window_t *wheadp; - -/* - * Some compilers define size_t as a unsigned 16 bit number while - * point_t and off_t might be defined as a signed 32 bit number. - * malloc(), realloc(), fread(), and fwrite() take size_t parameters, - * which means there will be some size limits because size_t is too - * small of a type. - */ -#define MAX_SIZE_T ((unsigned long) (size_t) ~0) - -extern int done; /* Quit flag. */ -extern int msgflag; /* True if msgline should be displayed. */ -extern point_t nscrap; /* Length of scrap buffer. */ -extern char_t *scrap; /* Allocated scrap buffer. */ -extern char_t *input; -extern char msgline[]; /* Message line input/output buffer. */ -extern char temp[]; /* Temporary buffer. */ -extern char searchtext[]; -extern char replace[]; -extern keymap_t *key_map; /* Command key mappings. */ -extern keymap_t keymap[]; -extern keymap_t *key_return; /* Command key return */ - -extern void fatal(char *); -extern void msg(char *, ...); -extern void display(window_t *, int); -extern void dispmsg(void); -extern void modeline(window_t *); -extern int utf8_size(char_t); -extern int prev_utf8_char_size(void); -extern void display_utf8(buffer_t *, char_t, int); -extern point_t lnstart(buffer_t *, point_t); -extern point_t lncolumn(buffer_t *, point_t, int); -extern point_t segstart(buffer_t *, point_t, point_t); -extern point_t segnext(buffer_t *, point_t, point_t); -extern point_t upup(buffer_t *, point_t); -extern point_t dndn(buffer_t *, point_t); -extern char_t *get_key(keymap_t *, keymap_t **); -extern int getinput(char *, char *, int, int); -extern int getfilename(char *, char *, int); -extern void display_prompt_and_response(char *, char *); -extern int growgap(buffer_t *, point_t); -extern point_t movegap(buffer_t *, point_t); -extern point_t pos(buffer_t *, char_t *); -extern char_t *ptr(buffer_t *, point_t); -extern int posix_file(char *); -extern int save(char *); -extern int load_file(char *); -extern int insert_file(char *, int); -extern void backsp(void); -extern void block(void); -extern void iblock(void); -extern void bottom(void); -extern void cut(void); -extern void copy(void); -extern void copy_cut(int); -extern void delete(void); -extern void toggle_overwrite_mode(void); -extern void down(void); -extern void insert(void); -extern void left(void); -extern void lnbegin(void); -extern void lnend(void); -extern void paste(void); -extern void pgdown(void); -extern void pgup(void); -extern void quit(void); -extern int yesno(int); -extern void quit_ask(void); -extern void redraw(void); -extern void readfile(void); -extern void insertfile(void); -extern void right(void); -extern void top(void); -extern void up(void); -extern void version(void); -extern void wleft(void); -extern void wright(void); -extern void writefile(void); -extern void savebuffer(void); -extern void showpos(void); -extern void killtoeol(void); -extern void gotoline(void); -extern void search(void); -extern void query_replace(void); -extern point_t line_to_point(int); -extern point_t search_forward(buffer_t *, point_t, char *); -extern point_t search_backwards(buffer_t *, point_t, char *); -extern void update_search_prompt(char *, char *); -extern void display_search_result(point_t, int, char *, char *); -extern buffer_t* find_buffer(char *, int); -extern void buffer_init(buffer_t *); -extern int delete_buffer(buffer_t *); -extern void next_buffer(void); -extern int count_buffers(void); -extern int modified_buffers(void); -extern void killbuffer(void); -extern char* get_buffer_name(buffer_t *); -extern void get_line_stats(int *, int *); -extern void query_replace(void); -extern window_t *new_window(); -extern void one_window(window_t *); -extern void split_window(); -extern void next_window(); -extern void delete_other_windows(); -extern void free_other_windows(); -extern void update_display(); -extern void w2b(window_t *); -extern void b2w(window_t *); -extern void associate_b2w(buffer_t *, window_t *); -extern void disassociate_b(window_t *); -extern void set_parse_state(buffer_t *, point_t); -extern void set_parse_state2(buffer_t *, point_t); -extern int parse_text(buffer_t *, point_t); -extern void resize_terminal(); diff --git a/ccode/hilite.c b/ccode/hilite.c deleted file mode 100644 index 57126ea..0000000 --- a/ccode/hilite.c +++ /dev/null @@ -1,105 +0,0 @@ -/* hlite.c, generic syntax hilighting, Atto Emacs, Hugh Barney, Public Domain, 2016 */ - -#include "header.h" - -int state = ID_DEFAULT; -int next_state = ID_DEFAULT; -int skip_count = 0; - -char_t get_at(buffer_t *bp, point_t pt) -{ - return (*ptr(bp, pt)); -} - -static char_t symbols[] = "{}[]()!'£$^&*-+=:;@~#<>,.?/\\|"; // minus % sign!! - -int is_symbol(char_t c) -{ - register char_t *p = symbols; - - for (p = symbols; *p != '\0'; p++) - if (*p == c) return 1; - return 0; -} - -void set_parse_state(buffer_t *bp, point_t pt) -{ - register point_t po; - - state = ID_DEFAULT; - next_state = ID_DEFAULT; - skip_count = 0; - - for (po =0; po < pt; po++) - parse_text(bp, po); -} - -int parse_text(buffer_t *bp, point_t pt) -{ - if (skip_count-- > 0) - return state; - - char_t c_now = get_at(bp, pt); - char_t c_next = get_at(bp, pt + 1); - state = next_state; - - if (state == ID_DEFAULT && c_now == '/' && c_next == '*') { - skip_count = 1; - return (next_state = state = ID_BLOCK_COMMENT); - } - - if (state == ID_BLOCK_COMMENT && c_now == '*' && c_next == '/') { - skip_count = 1; - next_state = ID_DEFAULT; - return ID_BLOCK_COMMENT; - } - - if (state == ID_DEFAULT && c_now == '/' && c_next == '/') { - skip_count = 1; - return (next_state = state = ID_LINE_COMMENT); - } - - if (state == ID_LINE_COMMENT && c_now == '\n') - return (next_state = ID_DEFAULT); - - if (state == ID_DEFAULT && c_now == '"') - return (next_state = ID_DOUBLE_STRING); - - if (state == ID_DOUBLE_STRING && c_now == '\\') { - skip_count = 1; - return (next_state = ID_DOUBLE_STRING); - } - - if (state == ID_DOUBLE_STRING && c_now == '"') { - next_state = ID_DEFAULT; - return ID_DOUBLE_STRING; - } - - if (state == ID_DEFAULT && c_now == '\'') - return (next_state = ID_SINGLE_STRING); - - if (state == ID_SINGLE_STRING && c_now == '\\') { - skip_count = 1; - return (next_state = ID_SINGLE_STRING); - } - - if (state == ID_SINGLE_STRING && c_now == '\'') { - next_state = ID_DEFAULT; - return ID_SINGLE_STRING; - } - - if (state != ID_DEFAULT) - return (next_state = state); - - if (state == ID_DEFAULT && c_now >= '0' && c_now <= '9') { - next_state = ID_DEFAULT; - return (state = ID_DIGITS); - } - - if (state == ID_DEFAULT && 1 == is_symbol(c_now)) { - next_state = ID_DEFAULT; - return (state = ID_SYMBOL); - } - - return (next_state = state); -} diff --git a/ccode/key.c b/ccode/key.c deleted file mode 100644 index a4b76ca..0000000 --- a/ccode/key.c +++ /dev/null @@ -1,167 +0,0 @@ -/* key.c, Atto Emacs, Public Domain, Hugh Barney, 2016, Derived from: Anthony's Editor January 93 */ - -#include "header.h" - -/* desc, keys, func */ -keymap_t keymap[] = { - {"C-a beginning-of-line ", "\x01", lnbegin }, - {"C-b backward-char ", "\x02", left }, - {"C-d delete ", "\x04", delete }, - {"C-e end-of-line ", "\x05", lnend }, - {"C-f foward-char ", "\x06", right }, - {"C-h backspace ", "\x08", backsp }, - {"C-k kill-to-eol ", "\x0B", killtoeol }, - {"C-l refresh ", "\x0C", redraw }, - {"C-n next-line ", "\x0E", down }, - {"C-p previous-line ", "\x10", up }, - {"C-r search ", "\x12", search }, - {"C-s search ", "\x13", search }, - {"C-v forward-page ", "\x16", pgdown }, - {"C-w kill-region ", "\x17", cut}, - {"C-y yank ", "\x19", paste}, - {"C-space set-mark ", "\x00", iblock }, /* ctrl-space */ - {"C-x 1 delete-other-window", "\x18\x31", delete_other_windows }, - {"C-x 2 split-window ", "\x18\x32", split_window }, - {"C-x o other-window ", "\x18\x6F", next_window }, - {"C-x = cursor-position ", "\x18\x3D", showpos }, - {"C-x i insert-file ", "\x18\x69", insertfile }, - {"C-x k kill-buffer ", "\x18\x6B", killbuffer }, - {"C-x C-n next-buffer ", "\x18\x0E", next_buffer }, - {"C-x n next-buffer ", "\x18\x6E", next_buffer }, - {"C-x C-f find-file ", "\x18\x06", readfile }, - {"C-x C-s save-buffer ", "\x18\x13", savebuffer }, - {"C-x C-w write-file ", "\x18\x17", writefile }, /* write and prompt for name */ - {"C-x C-c exit ", "\x18\x03", quit_ask }, - {"esc b back-word ", "\x1B\x62", wleft }, - {"esc f forward-word ", "\x1B\x66", wright }, - {"esc g gotoline ", "\x1B\x67", gotoline }, - {"esc k kill-region ", "\x1B\x6B", cut }, - {"esc r query-replace ", "\x1B\x72", query_replace }, - {"esc v backward-page ", "\x1B\x76", pgup }, - {"esc w copy-region ", "\x1B\x77", copy}, - {"esc @ set-mark ", "\x1B\x40", iblock }, /* esc-@ */ - {"esc < beg-of-buf ", "\x1B\x3C", top }, - {"esc > end-of-buf ", "\x1B\x3E", bottom }, - {"esc home, beg-of-buf ", "\x1B\x1B\x4F\x48", top }, - {"esc end, end-of-buf ", "\x1B\x1B\x4F\x46", bottom }, - {"esc up, beg-of-buf ", "\x1B\x1B\x5B\x41", top }, - {"esc down, end-of-buf ", "\x1B\x1B\x5B\x42", bottom }, - {"esc esc show-version ", "\x1B\x1B", version }, - {"ins toggle-overwrite-mode", "\x1B\x5B\x32\x7E", toggle_overwrite_mode }, /* Ins key */ - {"del forward-delete-char ", "\x1B\x5B\x33\x7E", delete }, /* Del key */ - {"backspace delete-left ", "\x7f", backsp }, - {"up previous-line ", "\x1B\x5B\x41", up }, - {"down next-line ", "\x1B\x5B\x42", down }, - {"left backward-character ", "\x1B\x5B\x44", left }, - {"right forward-character ", "\x1B\x5B\x43", right }, - {"home beginning-of-line ", "\x1B\x4F\x48", lnbegin }, - {"end end-of-line ", "\x1B\x4F\x46", lnend }, - {"home beginning-of-line ", "\x1B\x5B\x48", lnbegin }, - {"end end-of-line ", "\x1B\x5B\x46", lnend }, - {"pgup backward-page ", "\x1B\x5B\x35\x7E",pgup }, /* PgUp key */ - {"pgdn forward-page ", "\x1B\x5B\x36\x7E", pgdown }, /* PgDn key */ - {"resize resize-terminal ", "\x9A", resize_terminal }, - {"K_ERROR ", NULL, NULL } -}; - -char_t *get_key(keymap_t *keys, keymap_t **key_return) -{ - keymap_t *k; - int submatch; - static char_t buffer[K_BUFFER_LENGTH]; - static char_t *record = buffer; - - *key_return = NULL; - - /* if recorded bytes remain, return next recorded byte. */ - if (*record != '\0') { - *key_return = NULL; - return record++; - } - /* reset record buffer. */ - record = buffer; - - do { - assert(K_BUFFER_LENGTH > record - buffer); - /* read and record one byte. */ - *record++ = (unsigned)getch(); - *record = '\0'; - - /* if recorded bytes match any multi-byte sequence... */ - for (k = keys, submatch = 0; k->key_bytes != NULL; ++k) { - char_t *p, *q; - - for (p = buffer, q = (char_t *)k->key_bytes; *p == *q; ++p, ++q) { - /* an exact match */ - if (*q == '\0' && *p == '\0') { - record = buffer; - *record = '\0'; - *key_return = k; - return record; /* empty string */ - } - } - /* record bytes match part of a command sequence */ - if (*p == '\0' && *q != '\0') { - submatch = 1; - } - } - } while (submatch); - /* nothing matched, return recorded bytes. */ - record = buffer; - return (record++); -} - -int getinput(char *prompt, char *buf, int nbuf, int flag) -{ - int cpos = 0; - int c; - int start_col = strlen(prompt); - - mvaddstr(MSGLINE, 0, prompt); - clrtoeol(); - - if (flag == F_CLEAR) buf[0] = '\0'; - - /* if we have a default value print it and go to end of it */ - if (buf[0] != '\0') { - addstr(buf); - cpos = strlen(buf); - } - - for (;;) { - refresh(); - c = getch(); - /* ignore control keys other than backspace, cr, lf */ - if (c < 32 && c != 0x07 && c != 0x08 && c != 0x0a && c != 0x0d) - continue; - - switch(c) { - case 0x0a: /* cr, lf */ - case 0x0d: - buf[cpos] = '\0'; - return (cpos > 0 ? TRUE : FALSE); - - case 0x07: /* ctrl-g */ - return FALSE; - - case 0x7f: /* del, erase */ - case 0x08: /* backspace */ - if (cpos == 0) - continue; - - move(MSGLINE, start_col + cpos - 1); - addch(' '); - move(MSGLINE, start_col + cpos - 1); - buf[--cpos] = '\0'; - break; - - default: - if (cpos < nbuf -1) { - addch(c); - buf[cpos++] = c; - buf[cpos] ='\0'; - } - break; - } - } -} diff --git a/ccode/main.c b/ccode/main.c deleted file mode 100644 index 933b07b..0000000 --- a/ccode/main.c +++ /dev/null @@ -1,104 +0,0 @@ -/* main.c, Atto Emacs, Public Domain, Hugh Barney, 2016, Derived from: Anthony's Editor January 93 */ - -#include "header.h" - -int done; -point_t nscrap; -char_t *scrap; - -char_t *input; -int msgflag; -char msgline[TEMPBUF]; -char temp[TEMPBUF]; -char searchtext[STRBUF_M]; -char replace[STRBUF_M]; - -keymap_t *key_return; -keymap_t *key_map; -buffer_t *curbp; /* current buffer */ -buffer_t *bheadp; /* head of list of buffers */ -window_t *curwp; -window_t *wheadp; - -int main(int argc, char **argv) -{ - setlocale(LC_ALL, "") ; /* required for 3,4 byte UTF8 chars */ - if (initscr() == NULL) fatal("%s: Failed to initialize the screen.\n"); - raw(); - noecho(); - idlok(stdscr, TRUE); - - start_color(); - init_pair(ID_DEFAULT, COLOR_CYAN, COLOR_BLACK); /* alpha */ - init_pair(ID_SYMBOL, COLOR_WHITE, COLOR_BLACK); /* non alpha, non digit */ - init_pair(ID_MODELINE, COLOR_BLACK, COLOR_WHITE); /* modeline */ - init_pair(ID_DIGITS, COLOR_YELLOW, COLOR_BLACK); /* digits */ - init_pair(ID_BLOCK_COMMENT, COLOR_GREEN, COLOR_BLACK); /* block comments */ - init_pair(ID_LINE_COMMENT, COLOR_GREEN, COLOR_BLACK); /* line comments */ - init_pair(ID_SINGLE_STRING, COLOR_YELLOW, COLOR_BLACK); /* single quoted strings */ - init_pair(ID_DOUBLE_STRING, COLOR_YELLOW, COLOR_BLACK); /* double quoted strings */ - - if (1 < argc) { - curbp = find_buffer(argv[1], TRUE); - (void) insert_file(argv[1], FALSE); - /* Save filename irregardless of load() success. */ - strncpy(curbp->b_fname, argv[1], NAME_MAX); - curbp->b_fname[NAME_MAX] = '\0'; /* force truncation */ - } else { - curbp = find_buffer("*scratch*", TRUE); - strncpy(curbp->b_bname, "*scratch*", STRBUF_S); - } - - wheadp = curwp = new_window(); - one_window(curwp); - associate_b2w(curbp, curwp); - - if (!growgap(curbp, CHUNK)) fatal("%s: Failed to allocate required memory.\n"); - key_map = keymap; - - while (!done) { - update_display(); - input = get_key(key_map, &key_return); - - if (key_return != NULL) { - (key_return->func)(); - } else { - /* allow TAB and NEWLINE, otherwise any Control Char is 'Not bound' */ - if (*input > 31 || *input == 10 || *input == 9) - insert(); - else { - flushinp(); /* discard without writing in buffer */ - msg("Not bound"); - } - } - } - - if (scrap != NULL) free(scrap); - move(LINES-1, 0); - refresh(); - noraw(); - endwin(); - return 0; -} - -void fatal(char *msg) -{ - if (curscr != NULL) { - move(LINES-1, 0); - refresh(); - noraw(); - endwin(); - putchar('\n'); - } - fprintf(stderr, msg, PROG_NAME); - exit(1); -} - -void msg(char *msg, ...) -{ - va_list args; - va_start(args, msg); - (void)vsprintf(msgline, msg, args); - va_end(args); - msgflag = TRUE; -} diff --git a/ccode/makefile b/ccode/makefile deleted file mode 100644 index 1977fbe..0000000 --- a/ccode/makefile +++ /dev/null @@ -1,65 +0,0 @@ -# -# makefile -# -# Based on Anthonys Editor January 93 -# -# Public Domain 1991, 1993 by Anthony Howe. No warranty. -# - -CC = cc -CFLAGS = -O -Wall - -LD = cc -LIBS = -lncursesw - -CP = cp -MV = mv -RM = rm - -E = -O = .o - -OBJ = command$(O) display$(O) gap$(O) key$(O) search$(O) buffer$(O) replace$(O) window$(O) complete$(O) hilite$(O) main$(O) - -atto$(E) : $(OBJ) - $(LD) -o atto$(E) $(OBJ) $(LIBS) - -command$(O): command.c header.h - $(CC) $(CFLAGS) -c command.c - -complete$(O): complete.c header.h - $(CC) $(CFLAGS) -c complete.c - -display$(O): display.c header.h - $(CC) $(CFLAGS) -c display.c - -gap$(O): gap.c header.h - $(CC) $(CFLAGS) -c gap.c - -key$(O): key.c header.h - $(CC) $(CFLAGS) -c key.c - -search$(O): search.c header.h - $(CC) $(CFLAGS) -c search.c - -replace$(O): replace.c header.h - $(CC) $(CFLAGS) -c replace.c - -window$(O): window.c header.h - $(CC) $(CFLAGS) -c window.c - -buffer$(O): buffer.c header.h - $(CC) $(CFLAGS) -c buffer.c - -hilite$(O): hilite.c header.h - $(CC) $(CFLAGS) -c hilite.c - -main$(O): main.c header.h - $(CC) $(CFLAGS) -c main.c - -clean: - -$(RM) $(OBJ) atto$(E) - -install: - -$(MV) atto$(E) $(HOME)/bin - diff --git a/ccode/replace.c b/ccode/replace.c deleted file mode 100644 index a65b788..0000000 --- a/ccode/replace.c +++ /dev/null @@ -1,103 +0,0 @@ -/* replace.c, Atto Emacs, Hugh Barney, Public Domain, 2016 */ - -#include -#include "header.h" - -/*search for a string and replace it with another string */ -void query_replace(void) -{ - point_t o_point = curbp->b_point; - point_t l_point = -1; - point_t found; - char question[STRBUF_L]; - int slen, rlen; /* length of search and replace strings */ - int numsub = 0; /* number of substitutions */ - int ask = TRUE; - int c; - - searchtext[0] = '\0'; - replace[0] = '\0'; - - if (!getinput("Query replace: ", (char*)searchtext, STRBUF_M, F_CLEAR)) - return; - - if (!getinput("With: ", (char*)replace, STRBUF_M, F_CLEAR)) - return; - - slen = strlen(searchtext); - rlen = strlen(replace); - - /* build query replace question string */ - sprintf(question, "Replace '%s' with '%s' ? ", searchtext, replace); - - /* scan through the file, from point */ - numsub = 0; - while(TRUE) { - found = search_forward(curbp, curbp->b_point, searchtext); - - /* if not found set the point to the last point of replacement, or where we started */ - if (found == -1) { - curbp->b_point = (l_point == -1 ? o_point : l_point); - break; - } - - curbp->b_point = found; - /* search_forward places point at end of search, move to start of search */ - curbp->b_point -= slen; - - if (ask == TRUE) { - msg(question); - clrtoeol(); - - qprompt: - display(curwp, TRUE); - c = getch(); - - switch (c) { - case 'y': /* yes, substitute */ - break; - - case 'n': /* no, find next */ - curbp->b_point = found; /* set to end of search string */ - continue; - - case '!': /* yes/stop asking, do the lot */ - ask = FALSE; - break; - - case 0x1B: /* esc */ - flushinp(); /* discard any escape sequence without writing in buffer */ - case 'q': /* controlled exit */ - return; - - default: /* help me */ - msg("(y)es, (n)o, (!)do the rest, (q)uit"); - goto qprompt; - } - } - - if (rlen > slen) { - movegap(curbp, found); - /*check enough space in gap left */ - if (rlen - slen < curbp->b_egap - curbp->b_gap) - growgap(curbp, rlen - slen); - /* shrink gap right by r - s */ - curbp->b_gap = curbp->b_gap + (rlen - slen); - } else if (slen > rlen) { - movegap(curbp, found); - /* stretch gap left by s - r, no need to worry about space */ - curbp->b_gap = curbp->b_gap - (slen - rlen); - } else { - /* if rlen = slen, we just overwrite the chars, no need to move gap */ - } - - /* now just overwrite the chars at point in the buffer */ - l_point = curbp->b_point; - memcpy(ptr(curbp, curbp->b_point), replace, rlen * sizeof (char_t)); - curbp->b_flags |= B_MODIFIED; - curbp->b_point = found - (slen - rlen); /* end of replcement */ - numsub++; - } - - msg("%d substitutions", numsub); -} diff --git a/ccode/search.c b/ccode/search.c deleted file mode 100644 index acebcb2..0000000 --- a/ccode/search.c +++ /dev/null @@ -1,116 +0,0 @@ -/* search.c, Atto Emacs, Public Domain, Hugh Barney, 2016, Derived from: Anthony's Editor January 93 */ - -#include "header.h" - -#define FWD_SEARCH 1 -#define REV_SEARCH 2 - -void search() -{ - int cpos = 0; - int c; - point_t o_point = curbp->b_point; - point_t found; - - searchtext[0] = '\0'; - display_prompt_and_response("Search: ", searchtext); - cpos = strlen(searchtext); - - for (;;) { - c = getch(); - /* ignore control keys other than C-g, backspace, CR, C-s, C-R, ESC */ - if (c < 32 && c != 07 && c != 0x08 && c != 0x13 && c != 0x12 && c != 0x1b) - continue; - - switch(c) { - case 0x1b: /* esc */ - searchtext[cpos] = '\0'; - flushinp(); /* discard any escape sequence without writing in buffer */ - return; - - case 0x07: /* ctrl-g */ - curbp->b_point = o_point; - return; - - case 0x13: /* ctrl-s, do the search */ - found = search_forward(curbp, curbp->b_point, searchtext); - display_search_result(found, FWD_SEARCH, "Search: ", searchtext); - break; - - case 0x12: /* ctrl-r, do the search */ - found = search_backwards(curbp, curbp->b_point, searchtext); - display_search_result(found, REV_SEARCH, "Search: ", searchtext); - break; - - case 0x7f: /* del, erase */ - case 0x08: /* backspace */ - if (cpos == 0) - continue; - searchtext[--cpos] = '\0'; - display_prompt_and_response("Search: ", searchtext); - break; - - default: - if (cpos < STRBUF_M - 1) { - searchtext[cpos++] = c; - searchtext[cpos] = '\0'; - display_prompt_and_response("Search: ", searchtext); - } - break; - } - } -} - -void display_search_result(point_t found, int dir, char *prompt, char *search) -{ - if (found != -1 ) { - curbp->b_point = found; - msg("%s%s",prompt, search); - display(curwp, TRUE); - } else { - msg("Failing %s%s",prompt, search); - dispmsg(); - curbp->b_point = (dir == FWD_SEARCH ? 0 : pos(curbp, curbp->b_ebuf)); - } -} - -point_t search_forward(buffer_t *bp, point_t start_p, char *stext) -{ - point_t end_p = pos(bp, bp->b_ebuf); - point_t p,pp; - char* s; - - if (0 == strlen(stext)) - return start_p; - - for (p=start_p; p < end_p; p++) { - for (s=stext, pp=p; *s == *(ptr(bp, pp)) && *s !='\0' && pp < end_p; s++, pp++) - ; - - if (*s == '\0') - return pp; - } - - return -1; -} - -point_t search_backwards(buffer_t *bp, point_t start_p, char *stext) -{ - point_t p,pp; - char* s; - - if (0 == strlen(stext)) - return start_p; - - for (p=start_p; p >= 0; p--) { - for (s=stext, pp=p; *s == *(ptr(bp, pp)) && *s != '\0' && pp > -1; s++, pp++) - ; - - if (*s == '\0') { - if (p > 0) - p--; - return p; - } - } - return -1; -} diff --git a/ccode/window.c b/ccode/window.c deleted file mode 100644 index 6574c41..0000000 --- a/ccode/window.c +++ /dev/null @@ -1,104 +0,0 @@ -/* window.c, Atto Emacs, Hugh Barney, Public Domain, 2015 */ - -#include "header.h" - -int win_cnt = 0; - -window_t* new_window() -{ - window_t *wp = (window_t *)malloc(sizeof(window_t)); - - assert(wp != NULL); /* call fatal instead XXX */ - wp->w_next = NULL; - wp->w_bufp = NULL; - wp->w_point = 0; - wp->w_mark = NOMARK; - wp->w_top = 0; - wp->w_rows = 0; - wp->w_update = FALSE; - sprintf(wp->w_name, "W%d", ++win_cnt); - return wp; -} - -void one_window(window_t *wp) -{ - wp->w_top = 0; - wp->w_rows = LINES - 2; - wp->w_next = NULL; -} - -void split_window() -{ - window_t *wp, *wp2; - int ntru, ntrl; - - if (curwp->w_rows < 3) { - msg("Cannot split a %d line window", curwp->w_rows); - return; - } - - wp = new_window(); - associate_b2w(curwp->w_bufp,wp); - b2w(wp); /* inherit buffer settings */ - - ntru = (curwp->w_rows - 1) / 2; /* Upper size */ - ntrl = (curwp->w_rows - 1) - ntru; /* Lower size */ - - /* Old is upper window */ - curwp->w_rows = ntru; - wp->w_top = curwp->w_top + ntru + 1; - wp->w_rows = ntrl; - - /* insert it in the list */ - wp2 = curwp->w_next; - curwp->w_next = wp; - wp->w_next = wp2; - redraw(); /* mark the lot for update */ -} - -void next_window() { - curwp->w_update = TRUE; /* make sure modeline gets updated */ - curwp = (curwp->w_next == NULL ? wheadp : curwp->w_next); - curbp = curwp->w_bufp; - - if (curbp->b_cnt > 1) - w2b(curwp); /* push win vars to buffer */ -} - -void delete_other_windows() -{ - if (wheadp->w_next == NULL) { - msg("Only 1 window"); - return; - } - free_other_windows(curwp); -} - -void free_other_windows(window_t *winp) -{ - window_t *wp, *next; - - for (wp = next = wheadp; next != NULL; wp = next) { - next = wp->w_next; /* get next before a call to free() makes wp undefined */ - if (wp != winp) { - disassociate_b(wp); /* this window no longer references its buffer */ - free(wp); - } - } - - wheadp = curwp = winp; - one_window(winp); -} - -void associate_b2w(buffer_t *bp, window_t *wp) { - assert(bp != NULL); - assert(wp != NULL); - wp->w_bufp = bp; - bp->b_cnt++; -} - -void disassociate_b(window_t *wp) { - assert(wp != NULL); - assert(wp->w_bufp != NULL); - wp->w_bufp->b_cnt--; -} diff --git a/command.go b/command.go index 5590297..8f4ef0e 100644 --- a/command.go +++ b/command.go @@ -17,7 +17,6 @@ func (e *Editor) quitquit() { } func (e *Editor) up() { e.CurrentBuffer.PointUp() - //e.PointUp() } func (e *Editor) down() { e.CurrentBuffer.PointDown() @@ -37,9 +36,6 @@ func (e *Editor) bottom() { e.CurrentBuffer.SetPoint(e.CurrentBuffer.BufferLen() - 1) e.CurrentBuffer.Reframe = true e.CurrentBuffer.PageEnd = e.CurrentBuffer.BufferLen() - 1 - // if e.CurrentBuffer.PageEnd < e.CurrentBuffer.BufferLen() { - // e.CurrentBuffer.Reframe = true - // } } func (e *Editor) block() { e.CurrentBuffer.Mark = e.CurrentBuffer.Point() @@ -66,8 +62,6 @@ func (e *Editor) quitAsk() { /* flag = default answer, FALSE=n, TRUE=y */ func (e *Editor) yesno(flag bool, prompt string) bool { - //var ch rune - e.displayPromptAndResponse(prompt, "") e.MiniBufActive = true defer func() { e.MiniBufActive = false }() @@ -80,15 +74,6 @@ func (e *Editor) yesno(flag bool, prompt string) bool { return unicode.ToLower(ch) == 'y' } -// func (e *Editor) redraw() { -// termbox.Clear(termbox.ColorDefault, termbox.ColorDefault) -// e.CurrentWindow.Updated = true -// e.CurrentBuffer.Reframe = true -// e.msg("editor redraw") -// e.updateDisplay() -// termbox.Sync() -// termbox.Flush() -// } func (e *Editor) redraw() { termbox.Clear(termbox.ColorDefault, termbox.ColorDefault) @@ -157,7 +142,6 @@ func (e *Editor) insertfile() { } func (e *Editor) readfile() { - fname := e.getInput("Find file: ") if fname == "" { e.msg("Nope") @@ -168,13 +152,12 @@ func (e *Editor) readfile() { e.msg("Failed to find file \"%s\".", fname) return } - bp := e.FindBuffer(fname, true) e.CurrentWindow.DisassociateBuffer() e.CurrentBuffer = bp e.CurrentWindow.AssociateBuffer(bp) e.CurrentBuffer.Filename = fname - bp.SetText(string(dat)) + bp.setText(string(dat)) } func (e *Editor) savebuffer() { @@ -196,24 +179,20 @@ func (e *Editor) writefile() { func (e *Editor) killBuffer() { killbp := e.CurrentBuffer bcount := e.CountBuffers() - // do nothing if only buffer left is the scratch buffer if bcount == 1 && strings.Compare(e.GetBufferName(e.CurrentBuffer), "*scratch*") == 0 { return } - if e.CurrentBuffer.modified == true { q := "Discard changes (y/n) ?" if !e.yesno(false, q) { return } } - if bcount == 1 { bp := e.FindBuffer("*scratch*", true) bp.Filename = "*scratch*" } - e.nextBuffer() if killbp != e.CurrentBuffer { e.deleteBuffer(killbp) @@ -258,13 +237,10 @@ func (e *Editor) copyCut(cut bool) { rch, err := bp.RuneAt(l) if err != nil { e.msg("Copy/Cut failed. %s", err) - // log.Println("Copy/Cut failed.", err) } scrap[k] = rch - // log.Println("rune", rch) l++ } - //// log.Printf("CopyCut start %d len %d, %#v", start, extent, scrap) e.PasteBuffer = string(scrap) if cut == true { bp.Remove(start, extent) diff --git a/files.go b/files.go index 76557b7..60614b0 100644 --- a/files.go +++ b/files.go @@ -14,7 +14,6 @@ func (e *Editor) PosixFile(fname string) bool { if fn[0] == '_' { return false } - for f := range fn { if (unicode.IsLetter(rune(f))) && f != '.' && f != '_' && f != '-' && f != '/' { return false @@ -29,7 +28,7 @@ func (e *Editor) Save(fname string) bool { e.msg("Not a portable POSIX file name.") return false } - d1 := []byte(e.CurrentBuffer.GetText()) + d1 := []byte(e.CurrentBuffer.getText()) rch := d1[len(d1)-1] if rch != '\n' { prompt := "Last character is not newline. Add one?" @@ -54,14 +53,13 @@ func (e *Editor) LoadFile(fname string) bool { // InsertFile reads file into buffer at point func (e *Editor) InsertFile(fname string, modflag bool) bool { - bp := e.CurrentBuffer dat, err := ioutil.ReadFile(fname) if err != nil { e.msg("Failed to read and insert file \"%s\".", fname) } if modflag == true { - bp.SetText(string(dat)) + bp.setText(string(dat)) } else { bp.Insert(string(dat)) } diff --git a/hello/hello.go b/hello/hello.go deleted file mode 100644 index 4b8553a..0000000 --- a/hello/hello.go +++ /dev/null @@ -1,9 +0,0 @@ -package main - -import ( - "fmt" -) - -func main() { - fmt.Println("Hello, 世界") -} diff --git a/replace.go b/replace.go index 37bbaf3..c7eefa9 100644 --- a/replace.go +++ b/replace.go @@ -10,7 +10,6 @@ func (e *Editor) queryReplace() { } e.Replace = e.getInput("With: ") slen := len(e.Searchtext) - //rlen := len(e.Replace) bp := e.CurrentBuffer opoint := bp.Point() lpoint := -1 @@ -52,34 +51,27 @@ outer: switch c { case 'y': /* yes, substitute */ break inner - case 'n': /* no, find next */ bp.SetPoint(found) /* set to end of search string */ - //continue inner - case '!': /* yes/stop asking, do the lot */ ask = false break inner - //case 0x1B: /* esc */ //flushinp() /* discard any escape sequence without writing in buffer */ case 'q': /* controlled exit */ break outer - default: /* help me */ answer = e.getInput("(y)es, (n)o, (!)do the rest, (q)uit: ") //continue inner } } } - - for k := 0; k < slen; k++ { + for k := 0; k < slen; k++ { // delete found search text bp.Delete() } - bp.Insert(e.Replace) + bp.Insert(e.Replace) // qed lpoint = bp.Point() numsub++ } - e.msg("%d substitutions", numsub) } diff --git a/screenshots/atto.png b/screenshots/atto.png deleted file mode 100644 index e36c748..0000000 Binary files a/screenshots/atto.png and /dev/null differ diff --git a/search.go b/search.go index 36e6b0d..070cfed 100644 --- a/search.go +++ b/search.go @@ -24,11 +24,6 @@ func (e *Editor) displaySearchResult(found int, dir int, prompt string, search s } else { e.msg("Failing %s%s", prompt, search) e.displayMsg() - // if dir == fwdsearch { - // e.bottom() - // } else { - // e.top() - // } } } @@ -50,7 +45,6 @@ func (bp *Buffer) searchForward(startp int, stext string) int { } } if ss == len(s) { - // log.Printf("Found %s at pt %d\n", stext, pp) return pp } } @@ -75,7 +69,6 @@ func (bp *Buffer) searchBackwards(startp int, stext string) int { } } if ss == len(s) { - // log.Printf("Found %s at pt %d\n", stext, pp) return pp } } diff --git a/window.go b/window.go index 0c9d42e..db5741a 100644 --- a/window.go +++ b/window.go @@ -11,21 +11,20 @@ var winCount = 0 // Window main type type Window struct { - Editor *Editor - Next *Window /* w_next Next window */ - Buffer *Buffer /* w_bufp Buffer displayed in window */ - Point int // w_point - // - Mark int // w_mark - WinStart int // w_page - WinEnd int // w_epage - TopPt int /* w_top Origin 0 top row of window on screen */ - Rows int /* w_rows no. of rows of text in window */ - Row int /* w_row cursor row */ - Col int /* w_col cursor col */ - Updated bool // int w_update - Name string // w_name[STRBUF_S]; -} //window_t; + Editor *Editor + Next *Window /* w_next Next window */ + Buffer *Buffer /* w_bufp Buffer displayed in window */ + Point int // w_point + Mark int // w_mark + WinStart int // w_page + WinEnd int // w_epage + TopPt int /* w_top Origin 0 top row of window on screen */ + Rows int /* w_rows no. of rows of text in window */ + Row int /* w_row cursor row */ + Col int /* w_col cursor col */ + Updated bool // int w_update + Name string // w_name[STRBUF_S]; +} // NewWindow xxx func NewWindow(e *Editor) *Window { @@ -70,21 +69,8 @@ func (wp *Window) OnKey(ev *termbox.Event) { // log.Println("Alt!", ev.Key, ev.Ch) break } - //ch := ev.Ch - //// log.Printf("Win OnKey %#U Point is %d\n", ch, wp.Buffer.Point()) wp.Buffer.AddRune(ev.Ch) } - -} - -// PointForXY returns the Point location for X, Y in the WINDOW -// used to reverse map the mouse to a Buffer Point... -func (wp *Window) PointForXY(x, y int) (finalpt int) { - //10, 1 - // lpt := bp.PointForLine(y) - // c := x - 1 - // finalpt = lpt + c //bp.DataPointForBufferPoint(lpt + c) - return 0 //finalpt } // AssociateBuffer xxx @@ -104,14 +90,14 @@ func (wp *Window) DisassociateBuffer() { } // SyncBuffer xxx -func window2Buffer(w *Window) { //sync w2b win to buff +func window2Buffer(w *Window) { b := w.Buffer b.SetPoint(w.Point) b.PageStart = w.WinStart b.PageEnd = w.WinEnd b.PointRow = w.Row b.PointCol = w.Col - + // this should be figured out. /* fixup Pointers in other windows of the same buffer, if size of edit text changed */ // if b.Point() > b.OrigPoint { // sizeDelta := b.TextSize - b.PrevSize @@ -123,7 +109,7 @@ func window2Buffer(w *Window) { //sync w2b win to buff } // PushBuffer2Window xxx -func buffer2Window(w *Window) { // b2w +func buffer2Window(w *Window) { b := w.Buffer w.Point = b.Point() w.WinStart = b.PageStart