fortrangoingonforty/fgof-lineedit / fc251b7

Browse files

Scaffold lineedit package

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
fc251b7b58acd6e4850ae93addb0addc8aa13a9b
Parents
876e7d1
Tree
9c970b4

5 changed files

StatusFile+-
A README.md 99 0
A fpm.toml 20 0
A src/fgof_lineedit.f90 44 0
A src/fgof_lineedit_types.f90 19 0
A test/test_scaffold.f90 17 0
README.mdadded
@@ -0,0 +1,99 @@
1
+# fgof-lineedit
2
+
3
+Fortran-native line editing helpers for interactive CLI tools.
4
+
5
+`fgof-lineedit` is intended to be a small, standalone library that gives Fortran shells, REPLs, and interactive CLIs a friendlier editing surface than raw terminal reads.
6
+
7
+It is part of the [FortranGoingOnForty lib-modules](https://github.com/FortranGoingOnForty/lib-modules) catalog, but it is intended to stand on its own as a normal `fpm` package.
8
+
9
+Current v1 target:
10
+
11
+- editable line buffer and cursor model
12
+- prompt handling and rendered line state
13
+- history navigation and history storage hooks
14
+- completion and key-handling integration points
15
+- clean boundaries with future `fgof-termios` and `fgof-keys`
16
+
17
+Future scope:
18
+
19
+- richer readline-style editing commands
20
+- completion engines and menu UIs
21
+- prompt widgets and multi-line editing
22
+
23
+## Status
24
+
25
+Initial scaffold is in place.
26
+
27
+Implemented today:
28
+
29
+- public `fgof_lineedit` and `fgof_lineedit_types` modules
30
+- line editor and prompt-state types
31
+- prompt constructor and basic reset helper
32
+- smoke-test coverage and CI wiring
33
+
34
+Still to implement:
35
+
36
+- editable buffer operations
37
+- history and completion hooks
38
+- terminal integration and redraw behavior
39
+
40
+## Why Use It
41
+
42
+- line editing is repeatedly hand-built in shells, REPLs, and text tools
43
+- the Fortran ecosystem still lacks an obvious small default package here
44
+- it is meant to compose cleanly with `fgof-pty`, future `fgof-termios`, and future `fgof-keys`
45
+
46
+## Public API Shape
47
+
48
+Primary modules:
49
+
50
+- `fgof_lineedit`
51
+- `fgof_lineedit_types`
52
+
53
+Public types:
54
+
55
+- `lineedit_state`
56
+- `prompt_spec`
57
+
58
+Current public procedures:
59
+
60
+- `default_prompt`
61
+- `init_lineedit`
62
+- `reset_lineedit`
63
+
64
+## Quick Start
65
+
66
+```fortran
67
+program demo_lineedit
68
+  use fgof_lineedit, only : default_prompt, init_lineedit, lineedit_state
69
+  implicit none
70
+
71
+  type(lineedit_state) :: editor
72
+
73
+  call init_lineedit(editor, default_prompt("> "))
74
+  print "(A)", editor%prompt%text
75
+end program demo_lineedit
76
+```
77
+
78
+## Build And Test
79
+
80
+```bash
81
+fpm test
82
+```
83
+
84
+That is the baseline verification command locally and in CI.
85
+
86
+## Supported Platforms
87
+
88
+- macOS
89
+- Linux
90
+
91
+## Boundaries
92
+
93
+- intended to stay independently versioned and releasable
94
+- focused on editing state and library ergonomics, not full shell implementation
95
+- terminal-mode control should stay in a future companion package
96
+
97
+## License
98
+
99
+MIT
fpm.tomladded
@@ -0,0 +1,20 @@
1
+name = "fgof-lineedit"
2
+version = "0.1.0"
3
+license = "MIT"
4
+author = "FortranGoingOnForty"
5
+maintainer = "FortranGoingOnForty"
6
+copyright = "2026"
7
+description = "Fortran-native line editing helpers for interactive CLI tools"
8
+
9
+[build]
10
+auto-executables = false
11
+auto-tests = true
12
+auto-examples = false
13
+
14
+[install]
15
+library = true
16
+
17
+[fortran]
18
+implicit-typing = false
19
+implicit-external = false
20
+source-form = "free"
src/fgof_lineedit.f90added
@@ -0,0 +1,44 @@
1
+module fgof_lineedit
2
+  use fgof_lineedit_types, only : lineedit_state, prompt_spec
3
+  implicit none
4
+  private
5
+
6
+  public :: default_prompt
7
+  public :: init_lineedit
8
+  public :: lineedit_state
9
+  public :: prompt_spec
10
+  public :: reset_lineedit
11
+
12
+contains
13
+
14
+  function default_prompt(text) result(prompt)
15
+    character(len=*), intent(in) :: text
16
+    type(prompt_spec) :: prompt
17
+
18
+    prompt%text = text
19
+  end function default_prompt
20
+
21
+  subroutine init_lineedit(editor, prompt)
22
+    type(lineedit_state), intent(out) :: editor
23
+    type(prompt_spec), intent(in), optional :: prompt
24
+
25
+    if (present(prompt)) then
26
+      editor%prompt = prompt
27
+    else
28
+      editor%prompt = default_prompt("> ")
29
+    end if
30
+
31
+    editor%buffer = ""
32
+    editor%cursor = 1
33
+    editor%active = .true.
34
+  end subroutine init_lineedit
35
+
36
+  subroutine reset_lineedit(editor)
37
+    type(lineedit_state), intent(inout) :: editor
38
+
39
+    editor%buffer = ""
40
+    editor%cursor = 1
41
+    editor%active = .false.
42
+  end subroutine reset_lineedit
43
+
44
+end module fgof_lineedit
src/fgof_lineedit_types.f90added
@@ -0,0 +1,19 @@
1
+module fgof_lineedit_types
2
+  implicit none
3
+  private
4
+
5
+  public :: lineedit_state
6
+  public :: prompt_spec
7
+
8
+  type :: prompt_spec
9
+    character(len=:), allocatable :: text
10
+  end type prompt_spec
11
+
12
+  type :: lineedit_state
13
+    type(prompt_spec) :: prompt
14
+    character(len=:), allocatable :: buffer
15
+    integer :: cursor = 1
16
+    logical :: active = .false.
17
+  end type lineedit_state
18
+
19
+end module fgof_lineedit_types
test/test_scaffold.f90added
@@ -0,0 +1,17 @@
1
+program test_scaffold
2
+  use fgof_lineedit, only : default_prompt, init_lineedit, lineedit_state, reset_lineedit
3
+  implicit none
4
+
5
+  type(lineedit_state) :: editor
6
+
7
+  call init_lineedit(editor, default_prompt("line> "))
8
+  if (.not. editor%active) error stop "editor should start active"
9
+  if (editor%prompt%text /= "line> ") error stop "editor should preserve prompt text"
10
+  if (editor%buffer /= "") error stop "editor should start with an empty buffer"
11
+  if (editor%cursor /= 1) error stop "editor should start with cursor at 1"
12
+
13
+  call reset_lineedit(editor)
14
+  if (editor%active) error stop "reset should deactivate the editor"
15
+  if (editor%buffer /= "") error stop "reset should clear the buffer"
16
+  if (editor%cursor /= 1) error stop "reset should restore cursor position"
17
+end program test_scaffold