From a7967bc4e13883880559d3874187d5c123cdd64f Mon Sep 17 00:00:00 2001 From: Noboru Saito Date: Tue, 26 Dec 2023 10:29:04 +0900 Subject: [PATCH] Added input mode for section header number Added section-header-num to help-key and help options. README.md has also been updated, as it has been added to the help. Improved comments. --- README.md | 11 ++++++- oviewer/action.go | 18 +++++++++++ oviewer/draw.go | 2 +- oviewer/event.go | 2 ++ oviewer/input.go | 1 + oviewer/input_section_num.go | 61 ++++++++++++++++++++++++++++++++++++ oviewer/input_skip.go | 2 +- oviewer/input_viewmode.go | 2 +- oviewer/keybind.go | 4 +++ 9 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 oviewer/input_section_num.go diff --git a/README.md b/README.md index e82949ee..a662bb45 100644 --- a/README.md +++ b/README.md @@ -371,10 +371,14 @@ ov --section-delimiter "^#" --section-header README.md It is also useful as a pager for `git``. +The number of lines in section-header can be changed. + +You can specify the number of lines using the `--section-header-num` option or key input(default key `F7`). + ```gitconfig [pager] diff = "ov -F --section-delimiter '^diff' --section-header" - log = "ov -F --section-delimiter '^commit' --section-header" + log = "ov -F --section-delimiter '^commit' --section-header --section-header-num 3" ``` ### 3.10. Follow mode @@ -721,6 +725,7 @@ MemoryLimit: 1000 | -H, | --header int | number of header lines to be displayed constantly | | -h, | --help | help for ov | | | --help-key | display key bind information | +| | --hscroll-width [int\|int%\|.int] | width to scroll horizontally [int\|int%\|.int] (default "10%") | | | --incsearch[=true\|false] | incremental search (default true) | | -j, | --jump-target [int\|int%\|.int\|'section'] | jump target [int\|int%\|.int\|'section'] | | -n, | --line-number | line number mode | @@ -733,6 +738,7 @@ MemoryLimit: 1000 | | --regexp-search | regular expression search | | | --section-delimiter regexp | regexp for section delimiter .e.g. "^#" | | | --section-header | enable section-delimiter line as Header | +| | --section-header-num int | number of header lines (default 1) | | | --section-start int | section start position | | | --skip-extract | skip extracting compressed files | | | --skip-lines int | skip the number of lines | @@ -774,6 +780,8 @@ It can also be changed after startup. | [right] | * scroll to right | | [ctrl+left] | * scroll left half screen | | [ctrl+right] | * scroll right half screen | +| [ctrl+shift+left] | * scroll left specified width | +| [ctrl+shift+right] | * scroll right specified width | | [shift+Home] | * go to beginning of line | | [shift+End] | * go to end of line | | [g] | * go to line(input number or `.n` or `n%` allowed) | @@ -815,6 +823,7 @@ It can also be changed after startup. | [^] | * previous section | | [9] | * last section | | [F2] | * follow section mode toggle | +| [F7] | * section header number | | **Close and reload** | | | [ctrl+F9], [ctrl+alt+s] | * close file | | [ctrl+alt+l], [F5] | * reload file | diff --git a/oviewer/action.go b/oviewer/action.go index 43ba58ca..a8722062 100644 --- a/oviewer/action.go +++ b/oviewer/action.go @@ -321,6 +321,24 @@ func (root *Root) setSkipLines(input string) { root.setMessagef("Set skip lines %d", num) } +func (root *Root) setSectionNum(input string) { + num, err := strconv.Atoi(input) + if err != nil { + root.setMessagef("Set section header num: %s", ErrInvalidNumber.Error()) + return + } + if num < 0 { + root.setMessagef("Set section header num: %s", ErrOutOfRange.Error()) + return + } + if root.Doc.SectionHeaderNum == num { + return + } + + root.Doc.SectionHeaderNum = num + root.setMessagef("Set section header num %d", num) +} + // suspend suspends the current screen display and runs the shell. // It will return when you exit the shell. func (root *Root) suspend() { diff --git a/oviewer/draw.go b/oviewer/draw.go index 9989c43d..7157f188 100644 --- a/oviewer/draw.go +++ b/oviewer/draw.go @@ -120,7 +120,7 @@ func (root *Root) drawSectionHeader(lN int) int { } pn := lN - // If the line number is 0, it is the first line. + // prevSection searches for the section above the specified line. if pn == 0 { pn = 1 } diff --git a/oviewer/event.go b/oviewer/event.go index c7669a76..02e35e47 100644 --- a/oviewer/event.go +++ b/oviewer/event.go @@ -84,6 +84,8 @@ func (root *Root) eventLoop(ctx context.Context, quitChan chan<- struct{}) { root.setJumpTarget(ev.value) case *eventSaveBuffer: root.saveBuffer(ev.value) + case *eventSectionNum: + root.setSectionNum(ev.value) // tcell events case *tcell.EventResize: diff --git a/oviewer/input.go b/oviewer/input.go index 30c79354..6d0fb8be 100644 --- a/oviewer/input.go +++ b/oviewer/input.go @@ -29,6 +29,7 @@ const ( MultiColor // MultiColor is multi-word coloring. JumpTarget // JumpTarget is the position to display the search results. SaveBuffer // SaveBuffer is the save buffer. + SectionNum // SectionNum is the section number. ) // Input represents the status of various inputs. diff --git a/oviewer/input_section_num.go b/oviewer/input_section_num.go new file mode 100644 index 00000000..89c50c13 --- /dev/null +++ b/oviewer/input_section_num.go @@ -0,0 +1,61 @@ +package oviewer + +import ( + "strconv" + + "github.com/gdamore/tcell/v2" +) + +// setSectionNumMode sets the inputMode to SectionNum. +func (root *Root) setSectionNumMode() { + input := root.input + input.value = "" + input.cursorX = 0 + input.Event = newSectionNumEvent() +} + +// eventSectionNum represents the section num input mode. +type eventSectionNum struct { + tcell.EventTime + value string +} + +// newSectionNumEvent returns Event. +func newSectionNumEvent() *eventSectionNum { + return &eventSectionNum{} +} + +// Mode returns InputMode. +func (e *eventSectionNum) Mode() InputMode { + return SectionNum +} + +// Prompt returns the prompt string in the input field. +func (e *eventSectionNum) Prompt() string { + return "Section Num:" +} + +// Confirm returns the event when the input is confirmed. +func (e *eventSectionNum) Confirm(str string) tcell.Event { + e.value = str + e.SetEventNow() + return e +} + +// Up returns strings when the up key is pressed during input. +func (e *eventSectionNum) Up(str string) string { + n, err := strconv.Atoi(str) + if err != nil { + return "0" + } + return strconv.Itoa(n + 1) +} + +// Down returns strings when the down key is pressed during input. +func (e *eventSectionNum) Down(str string) string { + n, err := strconv.Atoi(str) + if err != nil || n <= 0 { + return "0" + } + return strconv.Itoa(n - 1) +} diff --git a/oviewer/input_skip.go b/oviewer/input_skip.go index 7859470a..9ff2d7c3 100644 --- a/oviewer/input_skip.go +++ b/oviewer/input_skip.go @@ -14,7 +14,7 @@ func (root *Root) setSkipLinesMode() { input.Event = newSkipLinesEvent() } -// eventSkipLines represents the goto input mode. +// eventSkipLines represents the skip lines input mode. type eventSkipLines struct { tcell.EventTime value string diff --git a/oviewer/input_viewmode.go b/oviewer/input_viewmode.go index ea92f0d9..f7bde499 100644 --- a/oviewer/input_viewmode.go +++ b/oviewer/input_viewmode.go @@ -19,7 +19,7 @@ func viewModeCandidate() *candidate { } } -// eventViewMode represents the mode input mode. +// eventViewMode represents the view mode input mode. type eventViewMode struct { tcell.EventTime clist *candidate diff --git a/oviewer/keybind.go b/oviewer/keybind.go index d1c99fb7..09d49d97 100644 --- a/oviewer/keybind.go +++ b/oviewer/keybind.go @@ -68,6 +68,7 @@ const ( actionSkipLines = "skip_lines" actionTabWidth = "tabwidth" actionGoLine = "goto" + actionSectionNum = "section_num" actionNextSearch = "next_search" actionNextBackSearch = "next_backsearch" actionNextDoc = "next_doc" @@ -147,6 +148,7 @@ func (root *Root) handlers() map[string]func() { actionSkipLines: root.setSkipLinesMode, actionTabWidth: root.setTabWidthMode, actionGoLine: root.setGoLineMode, + actionSectionNum: root.setSectionNumMode, actionNextSearch: root.sendNextSearch, actionNextBackSearch: root.sendNextBackSearch, actionNextDoc: root.nextDoc, @@ -229,6 +231,7 @@ func defaultKeyBinds() KeyBind { actionSkipLines: {"ctrl+s"}, actionTabWidth: {"t"}, actionGoLine: {"g"}, + actionSectionNum: {"F7"}, actionNextSearch: {"n"}, actionNextBackSearch: {"N"}, actionNextDoc: {"]"}, @@ -338,6 +341,7 @@ func (k KeyBind) String() string { k.writeKeyBind(&b, actionPrevSection, "previous section") k.writeKeyBind(&b, actionLastSection, "last section") k.writeKeyBind(&b, actionFollowSection, "follow section mode toggle") + k.writeKeyBind(&b, actionSectionNum, "section header number") fmt.Fprint(&b, "\n\tClose and reload\n") fmt.Fprint(&b, "\n")