mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2025-01-28 17:48:25 +00:00
Compare commits
2 Commits
4f2c274942
...
a5beb08ed7
Author | SHA1 | Date | |
---|---|---|---|
|
a5beb08ed7 | ||
|
45fc7b903d |
15
CHANGELOG.md
15
CHANGELOG.md
@ -16,7 +16,7 @@ CHANGELOG
|
|||||||
- Actions
|
- Actions
|
||||||
- `change-list-label`
|
- `change-list-label`
|
||||||
- `transform-list-label`
|
- `transform-list-label`
|
||||||
- Border and label for the input section (prompt and info)
|
- Border and label for the input section (prompt line and info line)
|
||||||
- Options
|
- Options
|
||||||
- `--input-border[=STYLE]`
|
- `--input-border[=STYLE]`
|
||||||
- `--input-label=LABEL`
|
- `--input-label=LABEL`
|
||||||
@ -29,6 +29,19 @@ CHANGELOG
|
|||||||
- Actions
|
- Actions
|
||||||
- `change-input-label`
|
- `change-input-label`
|
||||||
- `transform-input-label`
|
- `transform-input-label`
|
||||||
|
- Border and label for the header section
|
||||||
|
- Options
|
||||||
|
- `--header-border[=STYLE]`
|
||||||
|
- `--header-label=LABEL`
|
||||||
|
- `--header-label-pos=COL[:bottom]`
|
||||||
|
- Colors
|
||||||
|
- `header-fg` (`header`)
|
||||||
|
- `header-bg`
|
||||||
|
- `header-border`
|
||||||
|
- `header-label`
|
||||||
|
- Actions
|
||||||
|
- `change-header-label`
|
||||||
|
- `transform-header-label`
|
||||||
- Added `--preview-border[=STYLE]` as short for `--preview-window=border[-STYLE]`
|
- Added `--preview-border[=STYLE]` as short for `--preview-window=border[-STYLE]`
|
||||||
- You can specify `border-native` to `--tmux` so that native tmux border is used instead of `--border`. This can be useful if you start a different program from inside the popup.
|
- You can specify `border-native` to `--tmux` so that native tmux border is used instead of `--border`. This can be useful if you start a different program from inside the popup.
|
||||||
```sh
|
```sh
|
||||||
|
2
install
2
install
@ -83,7 +83,7 @@ ask() {
|
|||||||
check_binary() {
|
check_binary() {
|
||||||
echo -n " - Checking fzf executable ... "
|
echo -n " - Checking fzf executable ... "
|
||||||
local output
|
local output
|
||||||
output=$("$fzf_base"/bin/fzf --version 2>&1)
|
output=$(FZF_DEFAULT_OPTS= "$fzf_base"/bin/fzf --version 2>&1)
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Error: $output"
|
echo "Error: $output"
|
||||||
binary_error="Invalid binary"
|
binary_error="Invalid binary"
|
||||||
|
@ -308,7 +308,7 @@ Choose the layout (default: default)
|
|||||||
A synonym for \fB\-\-layout=reverse\fB
|
A synonym for \fB\-\-layout=reverse\fB
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BI "\-\-border" [=BORDER_OPT]
|
.BI "\-\-border" [=STYLE]
|
||||||
Draw border around the finder
|
Draw border around the finder
|
||||||
|
|
||||||
.br
|
.br
|
||||||
@ -387,6 +387,42 @@ the label. Label is printed on the top border line by default, add
|
|||||||
\fB:bottom\fR to put it on the border line on the bottom. The default value
|
\fB:bottom\fR to put it on the border line on the bottom. The default value
|
||||||
\fB0 (or \fBcenter\fR) will put the label at the center of the border line.
|
\fB0 (or \fBcenter\fR) will put the label at the center of the border line.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BI "\-\-list\-border" [=STYLE]
|
||||||
|
Draw border around the list section
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BI "\-\-list\-label" [=LABEL]
|
||||||
|
Label to print on the list border
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BI "\-\-list\-label\-pos" [=N[:top|bottom]]
|
||||||
|
Position of the list label
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BI "\-\-input\-border" [=STYLE]
|
||||||
|
Draw border around the input section
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BI "\-\-input\-label" [=LABEL]
|
||||||
|
Label to print on the input border
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BI "\-\-input\-label\-pos" [=N[:top|bottom]]
|
||||||
|
Position of the input label
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BI "\-\-header\-border" [=STYLE]
|
||||||
|
Draw border around the header section
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BI "\-\-header\-label" [=LABEL]
|
||||||
|
Label to print on the header border
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BI "\-\-header\-label\-pos" [=N[:top|bottom]]
|
||||||
|
Position of the header label
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B "\-\-no\-unicode"
|
.B "\-\-no\-unicode"
|
||||||
Use ASCII characters instead of Unicode drawing characters to draw borders,
|
Use ASCII characters instead of Unicode drawing characters to draw borders,
|
||||||
@ -563,7 +599,8 @@ color mappings.
|
|||||||
\fBlist\-bg \fRList section background
|
\fBlist\-bg \fRList section background
|
||||||
\fBselected\-bg \fRSelected line background
|
\fBselected\-bg \fRSelected line background
|
||||||
\fBpreview\-bg \fRPreview window background
|
\fBpreview\-bg \fRPreview window background
|
||||||
\fBinput\-bg \fRInput section background
|
\fBinput\-bg \fRInput window background (\fB\-\-input\-border\fR)
|
||||||
|
\fBheader\-bg \fRHeader window background (\fB\-\-header\-border\fR)
|
||||||
\fBhl \fRHighlighted substrings
|
\fBhl \fRHighlighted substrings
|
||||||
\fBselected\-hl \fRHighlighted substrings in the selected line
|
\fBselected\-hl \fRHighlighted substrings in the selected line
|
||||||
\fBcurrent\-fg (fg+) \fRText (current line)
|
\fBcurrent\-fg (fg+) \fRText (current line)
|
||||||
@ -579,16 +616,18 @@ color mappings.
|
|||||||
\fBseparator \fRHorizontal separator on info line
|
\fBseparator \fRHorizontal separator on info line
|
||||||
\fBpreview\-border \fRBorder around the preview window (\fB\-\-preview\fR)
|
\fBpreview\-border \fRBorder around the preview window (\fB\-\-preview\fR)
|
||||||
\fBpreview\-scrollbar \fRScrollbar
|
\fBpreview\-scrollbar \fRScrollbar
|
||||||
\fBinput\-border \fRBorder around the input section (\fB\-\-input\-border\fR)
|
\fBinput\-border \fRBorder around the input window (\fB\-\-input\-border\fR)
|
||||||
|
\fBheader\-border \fRBorder around the header window (\fB\-\-header\-border\fR)
|
||||||
\fBlabel \fRBorder label (\fB\-\-border\-label\fR, \fB\-\-list\-label\fR, \fB\-\-input\-label\fR, and \fB\-\-preview\-label\fR)
|
\fBlabel \fRBorder label (\fB\-\-border\-label\fR, \fB\-\-list\-label\fR, \fB\-\-input\-label\fR, and \fB\-\-preview\-label\fR)
|
||||||
\fBlist\-label \fRBorder label of the list section (\fB\-\-list\-label\fR)
|
\fBlist\-label \fRBorder label of the list section (\fB\-\-list\-label\fR)
|
||||||
\fBpreview\-label \fRBorder label of the preview window (\fB\-\-preview\-label\fR)
|
\fBpreview\-label \fRBorder label of the preview window (\fB\-\-preview\-label\fR)
|
||||||
\fBinput\-label \fRBorder label of the input section (\fB\-\-input\-label\fR)
|
\fBinput\-label \fRBorder label of the input window (\fB\-\-input\-label\fR)
|
||||||
|
\fBheader\-label \fRBorder label of the header window (\fB\-\-header\-label\fR)
|
||||||
\fBprompt \fRPrompt
|
\fBprompt \fRPrompt
|
||||||
\fBpointer \fRPointer to the current line
|
\fBpointer \fRPointer to the current line
|
||||||
\fBmarker \fRMulti\-select marker
|
\fBmarker \fRMulti\-select marker
|
||||||
\fBspinner \fRStreaming input indicator
|
\fBspinner \fRStreaming input indicator
|
||||||
\fBheader \fRHeader
|
\fBheader (header\-fg) \fRHeader
|
||||||
|
|
||||||
.B ANSI COLORS:
|
.B ANSI COLORS:
|
||||||
\fB\-1 \fRDefault terminal foreground/background color
|
\fB\-1 \fRDefault terminal foreground/background color
|
||||||
@ -1454,6 +1493,7 @@ A key or an event can be bound to one or more of the following actions.
|
|||||||
\fBcancel\fR (clear query string if not empty, abort fzf otherwise)
|
\fBcancel\fR (clear query string if not empty, abort fzf otherwise)
|
||||||
\fBchange\-border\-label(...)\fR (change \fB\-\-border\-label\fR to the given string)
|
\fBchange\-border\-label(...)\fR (change \fB\-\-border\-label\fR to the given string)
|
||||||
\fBchange\-header(...)\fR (change header to the given string; doesn't affect \fB\-\-header\-lines\fR)
|
\fBchange\-header(...)\fR (change header to the given string; doesn't affect \fB\-\-header\-lines\fR)
|
||||||
|
\fBchange\-header\-label(...)\fR (change \fB\-\-header\-label\fR to the given string)
|
||||||
\fBchange\-input\-label(...)\fR (change \fB\-\-input\-label\fR to the given string)
|
\fBchange\-input\-label(...)\fR (change \fB\-\-input\-label\fR to the given string)
|
||||||
\fBchange\-list\-label(...)\fR (change \fB\-\-list\-label\fR to the given string)
|
\fBchange\-list\-label(...)\fR (change \fB\-\-list\-label\fR to the given string)
|
||||||
\fBchange\-multi\fR (enable multi-select mode with no limit)
|
\fBchange\-multi\fR (enable multi-select mode with no limit)
|
||||||
@ -1540,6 +1580,7 @@ A key or an event can be bound to one or more of the following actions.
|
|||||||
\fBtransform(...)\fR (transform states using the output of an external command)
|
\fBtransform(...)\fR (transform states using the output of an external command)
|
||||||
\fBtransform\-border\-label(...)\fR (transform border label using an external command)
|
\fBtransform\-border\-label(...)\fR (transform border label using an external command)
|
||||||
\fBtransform\-header(...)\fR (transform header using an external command)
|
\fBtransform\-header(...)\fR (transform header using an external command)
|
||||||
|
\fBtransform\-header\-label(...)\fR (transform header label using an external command)
|
||||||
\fBtransform\-input\-label(...)\fR (transform input label using an external command)
|
\fBtransform\-input\-label(...)\fR (transform input label using an external command)
|
||||||
\fBtransform\-list\-label(...)\fR (transform list label using an external command)
|
\fBtransform\-list\-label(...)\fR (transform list label using an external command)
|
||||||
\fBtransform\-preview\-label(...)\fR (transform preview label using an external command)
|
\fBtransform\-preview\-label(...)\fR (transform preview label using an external command)
|
||||||
|
@ -28,110 +28,112 @@ func _() {
|
|||||||
_ = x[actChangeListLabel-17]
|
_ = x[actChangeListLabel-17]
|
||||||
_ = x[actChangeInputLabel-18]
|
_ = x[actChangeInputLabel-18]
|
||||||
_ = x[actChangeHeader-19]
|
_ = x[actChangeHeader-19]
|
||||||
_ = x[actChangeMulti-20]
|
_ = x[actChangeHeaderLabel-20]
|
||||||
_ = x[actChangePreviewLabel-21]
|
_ = x[actChangeMulti-21]
|
||||||
_ = x[actChangePrompt-22]
|
_ = x[actChangePreviewLabel-22]
|
||||||
_ = x[actChangeQuery-23]
|
_ = x[actChangePrompt-23]
|
||||||
_ = x[actClearScreen-24]
|
_ = x[actChangeQuery-24]
|
||||||
_ = x[actClearQuery-25]
|
_ = x[actClearScreen-25]
|
||||||
_ = x[actClearSelection-26]
|
_ = x[actClearQuery-26]
|
||||||
_ = x[actClose-27]
|
_ = x[actClearSelection-27]
|
||||||
_ = x[actDeleteChar-28]
|
_ = x[actClose-28]
|
||||||
_ = x[actDeleteCharEof-29]
|
_ = x[actDeleteChar-29]
|
||||||
_ = x[actEndOfLine-30]
|
_ = x[actDeleteCharEof-30]
|
||||||
_ = x[actFatal-31]
|
_ = x[actEndOfLine-31]
|
||||||
_ = x[actForwardChar-32]
|
_ = x[actFatal-32]
|
||||||
_ = x[actForwardWord-33]
|
_ = x[actForwardChar-33]
|
||||||
_ = x[actKillLine-34]
|
_ = x[actForwardWord-34]
|
||||||
_ = x[actKillWord-35]
|
_ = x[actKillLine-35]
|
||||||
_ = x[actUnixLineDiscard-36]
|
_ = x[actKillWord-36]
|
||||||
_ = x[actUnixWordRubout-37]
|
_ = x[actUnixLineDiscard-37]
|
||||||
_ = x[actYank-38]
|
_ = x[actUnixWordRubout-38]
|
||||||
_ = x[actBackwardKillWord-39]
|
_ = x[actYank-39]
|
||||||
_ = x[actSelectAll-40]
|
_ = x[actBackwardKillWord-40]
|
||||||
_ = x[actDeselectAll-41]
|
_ = x[actSelectAll-41]
|
||||||
_ = x[actToggle-42]
|
_ = x[actDeselectAll-42]
|
||||||
_ = x[actToggleSearch-43]
|
_ = x[actToggle-43]
|
||||||
_ = x[actToggleAll-44]
|
_ = x[actToggleSearch-44]
|
||||||
_ = x[actToggleDown-45]
|
_ = x[actToggleAll-45]
|
||||||
_ = x[actToggleUp-46]
|
_ = x[actToggleDown-46]
|
||||||
_ = x[actToggleIn-47]
|
_ = x[actToggleUp-47]
|
||||||
_ = x[actToggleOut-48]
|
_ = x[actToggleIn-48]
|
||||||
_ = x[actToggleTrack-49]
|
_ = x[actToggleOut-49]
|
||||||
_ = x[actToggleTrackCurrent-50]
|
_ = x[actToggleTrack-50]
|
||||||
_ = x[actToggleHeader-51]
|
_ = x[actToggleTrackCurrent-51]
|
||||||
_ = x[actToggleWrap-52]
|
_ = x[actToggleHeader-52]
|
||||||
_ = x[actToggleMultiLine-53]
|
_ = x[actToggleWrap-53]
|
||||||
_ = x[actToggleHscroll-54]
|
_ = x[actToggleMultiLine-54]
|
||||||
_ = x[actTrackCurrent-55]
|
_ = x[actToggleHscroll-55]
|
||||||
_ = x[actUntrackCurrent-56]
|
_ = x[actTrackCurrent-56]
|
||||||
_ = x[actDown-57]
|
_ = x[actUntrackCurrent-57]
|
||||||
_ = x[actUp-58]
|
_ = x[actDown-58]
|
||||||
_ = x[actPageUp-59]
|
_ = x[actUp-59]
|
||||||
_ = x[actPageDown-60]
|
_ = x[actPageUp-60]
|
||||||
_ = x[actPosition-61]
|
_ = x[actPageDown-61]
|
||||||
_ = x[actHalfPageUp-62]
|
_ = x[actPosition-62]
|
||||||
_ = x[actHalfPageDown-63]
|
_ = x[actHalfPageUp-63]
|
||||||
_ = x[actOffsetUp-64]
|
_ = x[actHalfPageDown-64]
|
||||||
_ = x[actOffsetDown-65]
|
_ = x[actOffsetUp-65]
|
||||||
_ = x[actOffsetMiddle-66]
|
_ = x[actOffsetDown-66]
|
||||||
_ = x[actJump-67]
|
_ = x[actOffsetMiddle-67]
|
||||||
_ = x[actJumpAccept-68]
|
_ = x[actJump-68]
|
||||||
_ = x[actPrintQuery-69]
|
_ = x[actJumpAccept-69]
|
||||||
_ = x[actRefreshPreview-70]
|
_ = x[actPrintQuery-70]
|
||||||
_ = x[actReplaceQuery-71]
|
_ = x[actRefreshPreview-71]
|
||||||
_ = x[actToggleSort-72]
|
_ = x[actReplaceQuery-72]
|
||||||
_ = x[actShowPreview-73]
|
_ = x[actToggleSort-73]
|
||||||
_ = x[actHidePreview-74]
|
_ = x[actShowPreview-74]
|
||||||
_ = x[actTogglePreview-75]
|
_ = x[actHidePreview-75]
|
||||||
_ = x[actTogglePreviewWrap-76]
|
_ = x[actTogglePreview-76]
|
||||||
_ = x[actTransform-77]
|
_ = x[actTogglePreviewWrap-77]
|
||||||
_ = x[actTransformBorderLabel-78]
|
_ = x[actTransform-78]
|
||||||
_ = x[actTransformListLabel-79]
|
_ = x[actTransformBorderLabel-79]
|
||||||
_ = x[actTransformInputLabel-80]
|
_ = x[actTransformListLabel-80]
|
||||||
_ = x[actTransformHeader-81]
|
_ = x[actTransformInputLabel-81]
|
||||||
_ = x[actTransformPreviewLabel-82]
|
_ = x[actTransformHeader-82]
|
||||||
_ = x[actTransformPrompt-83]
|
_ = x[actTransformHeaderLabel-83]
|
||||||
_ = x[actTransformQuery-84]
|
_ = x[actTransformPreviewLabel-84]
|
||||||
_ = x[actPreview-85]
|
_ = x[actTransformPrompt-85]
|
||||||
_ = x[actChangePreview-86]
|
_ = x[actTransformQuery-86]
|
||||||
_ = x[actChangePreviewWindow-87]
|
_ = x[actPreview-87]
|
||||||
_ = x[actPreviewTop-88]
|
_ = x[actChangePreview-88]
|
||||||
_ = x[actPreviewBottom-89]
|
_ = x[actChangePreviewWindow-89]
|
||||||
_ = x[actPreviewUp-90]
|
_ = x[actPreviewTop-90]
|
||||||
_ = x[actPreviewDown-91]
|
_ = x[actPreviewBottom-91]
|
||||||
_ = x[actPreviewPageUp-92]
|
_ = x[actPreviewUp-92]
|
||||||
_ = x[actPreviewPageDown-93]
|
_ = x[actPreviewDown-93]
|
||||||
_ = x[actPreviewHalfPageUp-94]
|
_ = x[actPreviewPageUp-94]
|
||||||
_ = x[actPreviewHalfPageDown-95]
|
_ = x[actPreviewPageDown-95]
|
||||||
_ = x[actPrevHistory-96]
|
_ = x[actPreviewHalfPageUp-96]
|
||||||
_ = x[actPrevSelected-97]
|
_ = x[actPreviewHalfPageDown-97]
|
||||||
_ = x[actPrint-98]
|
_ = x[actPrevHistory-98]
|
||||||
_ = x[actPut-99]
|
_ = x[actPrevSelected-99]
|
||||||
_ = x[actNextHistory-100]
|
_ = x[actPrint-100]
|
||||||
_ = x[actNextSelected-101]
|
_ = x[actPut-101]
|
||||||
_ = x[actExecute-102]
|
_ = x[actNextHistory-102]
|
||||||
_ = x[actExecuteSilent-103]
|
_ = x[actNextSelected-103]
|
||||||
_ = x[actExecuteMulti-104]
|
_ = x[actExecute-104]
|
||||||
_ = x[actSigStop-105]
|
_ = x[actExecuteSilent-105]
|
||||||
_ = x[actFirst-106]
|
_ = x[actExecuteMulti-106]
|
||||||
_ = x[actLast-107]
|
_ = x[actSigStop-107]
|
||||||
_ = x[actReload-108]
|
_ = x[actFirst-108]
|
||||||
_ = x[actReloadSync-109]
|
_ = x[actLast-109]
|
||||||
_ = x[actDisableSearch-110]
|
_ = x[actReload-110]
|
||||||
_ = x[actEnableSearch-111]
|
_ = x[actReloadSync-111]
|
||||||
_ = x[actSelect-112]
|
_ = x[actDisableSearch-112]
|
||||||
_ = x[actDeselect-113]
|
_ = x[actEnableSearch-113]
|
||||||
_ = x[actUnbind-114]
|
_ = x[actSelect-114]
|
||||||
_ = x[actRebind-115]
|
_ = x[actDeselect-115]
|
||||||
_ = x[actBecome-116]
|
_ = x[actUnbind-116]
|
||||||
_ = x[actShowHeader-117]
|
_ = x[actRebind-117]
|
||||||
_ = x[actHideHeader-118]
|
_ = x[actBecome-118]
|
||||||
|
_ = x[actShowHeader-119]
|
||||||
|
_ = x[actHideHeader-120]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _actionType_name = "actIgnoreactStartactClickactInvalidactCharactMouseactBeginningOfLineactAbortactAcceptactAcceptNonEmptyactAcceptOrPrintQueryactBackwardCharactBackwardDeleteCharactBackwardDeleteCharEofactBackwardWordactCancelactChangeBorderLabelactChangeListLabelactChangeInputLabelactChangeHeaderactChangeMultiactChangePreviewLabelactChangePromptactChangeQueryactClearScreenactClearQueryactClearSelectionactCloseactDeleteCharactDeleteCharEofactEndOfLineactFatalactForwardCharactForwardWordactKillLineactKillWordactUnixLineDiscardactUnixWordRuboutactYankactBackwardKillWordactSelectAllactDeselectAllactToggleactToggleSearchactToggleAllactToggleDownactToggleUpactToggleInactToggleOutactToggleTrackactToggleTrackCurrentactToggleHeaderactToggleWrapactToggleMultiLineactToggleHscrollactTrackCurrentactUntrackCurrentactDownactUpactPageUpactPageDownactPositionactHalfPageUpactHalfPageDownactOffsetUpactOffsetDownactOffsetMiddleactJumpactJumpAcceptactPrintQueryactRefreshPreviewactReplaceQueryactToggleSortactShowPreviewactHidePreviewactTogglePreviewactTogglePreviewWrapactTransformactTransformBorderLabelactTransformListLabelactTransformInputLabelactTransformHeaderactTransformPreviewLabelactTransformPromptactTransformQueryactPreviewactChangePreviewactChangePreviewWindowactPreviewTopactPreviewBottomactPreviewUpactPreviewDownactPreviewPageUpactPreviewPageDownactPreviewHalfPageUpactPreviewHalfPageDownactPrevHistoryactPrevSelectedactPrintactPutactNextHistoryactNextSelectedactExecuteactExecuteSilentactExecuteMultiactSigStopactFirstactLastactReloadactReloadSyncactDisableSearchactEnableSearchactSelectactDeselectactUnbindactRebindactBecomeactShowHeaderactHideHeader"
|
const _actionType_name = "actIgnoreactStartactClickactInvalidactCharactMouseactBeginningOfLineactAbortactAcceptactAcceptNonEmptyactAcceptOrPrintQueryactBackwardCharactBackwardDeleteCharactBackwardDeleteCharEofactBackwardWordactCancelactChangeBorderLabelactChangeListLabelactChangeInputLabelactChangeHeaderactChangeHeaderLabelactChangeMultiactChangePreviewLabelactChangePromptactChangeQueryactClearScreenactClearQueryactClearSelectionactCloseactDeleteCharactDeleteCharEofactEndOfLineactFatalactForwardCharactForwardWordactKillLineactKillWordactUnixLineDiscardactUnixWordRuboutactYankactBackwardKillWordactSelectAllactDeselectAllactToggleactToggleSearchactToggleAllactToggleDownactToggleUpactToggleInactToggleOutactToggleTrackactToggleTrackCurrentactToggleHeaderactToggleWrapactToggleMultiLineactToggleHscrollactTrackCurrentactUntrackCurrentactDownactUpactPageUpactPageDownactPositionactHalfPageUpactHalfPageDownactOffsetUpactOffsetDownactOffsetMiddleactJumpactJumpAcceptactPrintQueryactRefreshPreviewactReplaceQueryactToggleSortactShowPreviewactHidePreviewactTogglePreviewactTogglePreviewWrapactTransformactTransformBorderLabelactTransformListLabelactTransformInputLabelactTransformHeaderactTransformHeaderLabelactTransformPreviewLabelactTransformPromptactTransformQueryactPreviewactChangePreviewactChangePreviewWindowactPreviewTopactPreviewBottomactPreviewUpactPreviewDownactPreviewPageUpactPreviewPageDownactPreviewHalfPageUpactPreviewHalfPageDownactPrevHistoryactPrevSelectedactPrintactPutactNextHistoryactNextSelectedactExecuteactExecuteSilentactExecuteMultiactSigStopactFirstactLastactReloadactReloadSyncactDisableSearchactEnableSearchactSelectactDeselectactUnbindactRebindactBecomeactShowHeaderactHideHeader"
|
||||||
|
|
||||||
var _actionType_index = [...]uint16{0, 9, 17, 25, 35, 42, 50, 68, 76, 85, 102, 123, 138, 159, 183, 198, 207, 227, 245, 264, 279, 293, 314, 329, 343, 357, 370, 387, 395, 408, 424, 436, 444, 458, 472, 483, 494, 512, 529, 536, 555, 567, 581, 590, 605, 617, 630, 641, 652, 664, 678, 699, 714, 727, 745, 761, 776, 793, 800, 805, 814, 825, 836, 849, 864, 875, 888, 903, 910, 923, 936, 953, 968, 981, 995, 1009, 1025, 1045, 1057, 1080, 1101, 1123, 1141, 1165, 1183, 1200, 1210, 1226, 1248, 1261, 1277, 1289, 1303, 1319, 1337, 1357, 1379, 1393, 1408, 1416, 1422, 1436, 1451, 1461, 1477, 1492, 1502, 1510, 1517, 1526, 1539, 1555, 1570, 1579, 1590, 1599, 1608, 1617, 1630, 1643}
|
var _actionType_index = [...]uint16{0, 9, 17, 25, 35, 42, 50, 68, 76, 85, 102, 123, 138, 159, 183, 198, 207, 227, 245, 264, 279, 299, 313, 334, 349, 363, 377, 390, 407, 415, 428, 444, 456, 464, 478, 492, 503, 514, 532, 549, 556, 575, 587, 601, 610, 625, 637, 650, 661, 672, 684, 698, 719, 734, 747, 765, 781, 796, 813, 820, 825, 834, 845, 856, 869, 884, 895, 908, 923, 930, 943, 956, 973, 988, 1001, 1015, 1029, 1045, 1065, 1077, 1100, 1121, 1143, 1161, 1184, 1208, 1226, 1243, 1253, 1269, 1291, 1304, 1320, 1332, 1346, 1362, 1380, 1400, 1422, 1436, 1451, 1459, 1465, 1479, 1494, 1504, 1520, 1535, 1545, 1553, 1560, 1569, 1582, 1598, 1613, 1622, 1633, 1642, 1651, 1660, 1673, 1686}
|
||||||
|
|
||||||
func (i actionType) String() string {
|
func (i actionType) String() string {
|
||||||
if i < 0 || i >= actionType(len(_actionType_index)-1) {
|
if i < 0 || i >= actionType(len(_actionType_index)-1) {
|
||||||
|
@ -103,6 +103,14 @@ Usage: fzf [options]
|
|||||||
[POSITIVE_INTEGER: columns from left|
|
[POSITIVE_INTEGER: columns from left|
|
||||||
NEGATIVE_INTEGER: columns from right][:bottom]
|
NEGATIVE_INTEGER: columns from right][:bottom]
|
||||||
(default: 0 or center)
|
(default: 0 or center)
|
||||||
|
--header-border[=STYLE] Draw border around the header section
|
||||||
|
[rounded|sharp|bold|block|thinblock|double|horizontal|vertical|
|
||||||
|
top|bottom|left|right|none] (default: rounded)
|
||||||
|
--header-label=LABEL Label to print on the header border
|
||||||
|
--header-label-pos=COL Position of the header label
|
||||||
|
[POSITIVE_INTEGER: columns from left|
|
||||||
|
NEGATIVE_INTEGER: columns from right][:bottom]
|
||||||
|
(default: 0 or center)
|
||||||
--margin=MARGIN Screen margin (TRBL | TB,RL | T,RL,B | T,R,B,L)
|
--margin=MARGIN Screen margin (TRBL | TB,RL | T,RL,B | T,R,B,L)
|
||||||
--padding=PADDING Padding inside border (TRBL | TB,RL | T,RL,B | T,R,B,L)
|
--padding=PADDING Padding inside border (TRBL | TB,RL | T,RL,B | T,R,B,L)
|
||||||
--info=STYLE Finder info style
|
--info=STYLE Finder info style
|
||||||
@ -545,7 +553,9 @@ type Options struct {
|
|||||||
BorderShape tui.BorderShape
|
BorderShape tui.BorderShape
|
||||||
ListBorderShape tui.BorderShape
|
ListBorderShape tui.BorderShape
|
||||||
InputBorderShape tui.BorderShape
|
InputBorderShape tui.BorderShape
|
||||||
|
HeaderBorderShape tui.BorderShape
|
||||||
InputLabel labelOpts
|
InputLabel labelOpts
|
||||||
|
HeaderLabel labelOpts
|
||||||
BorderLabel labelOpts
|
BorderLabel labelOpts
|
||||||
ListLabel labelOpts
|
ListLabel labelOpts
|
||||||
PreviewLabel labelOpts
|
PreviewLabel labelOpts
|
||||||
@ -1251,6 +1261,10 @@ func parseTheme(defaultTheme *tui.ColorTheme, str string) (*tui.ColorTheme, erro
|
|||||||
mergeAttr(&theme.InputBorder)
|
mergeAttr(&theme.InputBorder)
|
||||||
case "input-label":
|
case "input-label":
|
||||||
mergeAttr(&theme.InputLabel)
|
mergeAttr(&theme.InputLabel)
|
||||||
|
case "header-border":
|
||||||
|
mergeAttr(&theme.HeaderBorder)
|
||||||
|
case "header-label":
|
||||||
|
mergeAttr(&theme.HeaderLabel)
|
||||||
case "spinner":
|
case "spinner":
|
||||||
mergeAttr(&theme.Spinner)
|
mergeAttr(&theme.Spinner)
|
||||||
case "info":
|
case "info":
|
||||||
@ -1259,8 +1273,10 @@ func parseTheme(defaultTheme *tui.ColorTheme, str string) (*tui.ColorTheme, erro
|
|||||||
mergeAttr(&theme.Cursor)
|
mergeAttr(&theme.Cursor)
|
||||||
case "marker":
|
case "marker":
|
||||||
mergeAttr(&theme.Marker)
|
mergeAttr(&theme.Marker)
|
||||||
case "header":
|
case "header", "header-fg":
|
||||||
mergeAttr(&theme.Header)
|
mergeAttr(&theme.Header)
|
||||||
|
case "header-bg":
|
||||||
|
mergeAttr(&theme.HeaderBg)
|
||||||
default:
|
default:
|
||||||
fail()
|
fail()
|
||||||
}
|
}
|
||||||
@ -1314,7 +1330,7 @@ const (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
executeRegexp = regexp.MustCompile(
|
executeRegexp = regexp.MustCompile(
|
||||||
`(?si)[:+](become|execute(?:-multi|-silent)?|reload(?:-sync)?|preview|(?:change|transform)-(?:header|query|prompt|border-label|list-label|preview-label|input-label)|transform|change-(?:preview-window|preview|multi)|(?:re|un)bind|pos|put|print)`)
|
`(?si)[:+](become|execute(?:-multi|-silent)?|reload(?:-sync)?|preview|(?:change|transform)-(?:query|prompt|(?:border|list|preview|input|header)-label|header)|transform|change-(?:preview-window|preview|multi)|(?:re|un)bind|pos|put|print)`)
|
||||||
splitRegexp = regexp.MustCompile("[,:]+")
|
splitRegexp = regexp.MustCompile("[,:]+")
|
||||||
actionNameRegexp = regexp.MustCompile("(?i)^[a-z-]+")
|
actionNameRegexp = regexp.MustCompile("(?i)^[a-z-]+")
|
||||||
}
|
}
|
||||||
@ -1680,6 +1696,8 @@ func isExecuteAction(str string) actionType {
|
|||||||
return actChangePreviewLabel
|
return actChangePreviewLabel
|
||||||
case "change-input-label":
|
case "change-input-label":
|
||||||
return actChangeInputLabel
|
return actChangeInputLabel
|
||||||
|
case "change-header-label":
|
||||||
|
return actChangeHeaderLabel
|
||||||
case "change-preview-window":
|
case "change-preview-window":
|
||||||
return actChangePreviewWindow
|
return actChangePreviewWindow
|
||||||
case "change-preview":
|
case "change-preview":
|
||||||
@ -1712,6 +1730,8 @@ func isExecuteAction(str string) actionType {
|
|||||||
return actTransformPreviewLabel
|
return actTransformPreviewLabel
|
||||||
case "transform-input-label":
|
case "transform-input-label":
|
||||||
return actTransformInputLabel
|
return actTransformInputLabel
|
||||||
|
case "transform-header-label":
|
||||||
|
return actTransformHeaderLabel
|
||||||
case "transform-header":
|
case "transform-header":
|
||||||
return actTransformHeader
|
return actTransformHeader
|
||||||
case "transform-prompt":
|
case "transform-prompt":
|
||||||
@ -2542,6 +2562,27 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
|||||||
if err := parseLabelPosition(&opts.ListLabel, pos); err != nil {
|
if err := parseLabelPosition(&opts.ListLabel, pos); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
case "--no-header-border":
|
||||||
|
opts.HeaderBorderShape = tui.BorderNone
|
||||||
|
case "--header-border":
|
||||||
|
hasArg, arg := optionalNextString(allArgs, &i)
|
||||||
|
if opts.HeaderBorderShape, err = parseBorder(arg, !hasArg); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case "--no-header-label":
|
||||||
|
opts.HeaderLabel.label = ""
|
||||||
|
case "--header-label":
|
||||||
|
if opts.HeaderLabel.label, err = nextString(allArgs, &i, "header label required"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case "--header-label-pos":
|
||||||
|
pos, err := nextString(allArgs, &i, "header label position required (positive or negative integer or 'center')")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := parseLabelPosition(&opts.HeaderLabel, pos); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
case "--no-input-border":
|
case "--no-input-border":
|
||||||
opts.InputBorderShape = tui.BorderNone
|
opts.InputBorderShape = tui.BorderNone
|
||||||
case "--input-border":
|
case "--input-border":
|
||||||
@ -3003,6 +3044,10 @@ func postProcessOptions(opts *Options) error {
|
|||||||
opts.InputBorderShape = tui.BorderNone
|
opts.InputBorderShape = tui.BorderNone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opts.HeaderBorderShape == tui.BorderUndefined {
|
||||||
|
opts.HeaderBorderShape = tui.BorderNone
|
||||||
|
}
|
||||||
|
|
||||||
if opts.Pointer == nil {
|
if opts.Pointer == nil {
|
||||||
defaultPointer := "▌"
|
defaultPointer := "▌"
|
||||||
if !opts.Unicode {
|
if !opts.Unicode {
|
||||||
|
238
src/terminal.go
238
src/terminal.go
@ -180,13 +180,13 @@ type itemLine struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) markEmptyLine(line int) {
|
func (t *Terminal) markEmptyLine(line int) {
|
||||||
if t.window != t.inputWindow {
|
if t.window != t.inputWindow && t.window != t.headerWindow {
|
||||||
t.prevLines[line] = itemLine{valid: true, firstLine: line, empty: true}
|
t.prevLines[line] = itemLine{valid: true, firstLine: line, empty: true}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) markOtherLine(line int) {
|
func (t *Terminal) markOtherLine(line int) {
|
||||||
if t.window != t.inputWindow {
|
if t.window != t.inputWindow && t.window != t.headerWindow {
|
||||||
t.prevLines[line] = itemLine{valid: true, firstLine: line, other: true}
|
t.prevLines[line] = itemLine{valid: true, firstLine: line, other: true}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,6 +249,9 @@ type Terminal struct {
|
|||||||
inputLabel labelPrinter
|
inputLabel labelPrinter
|
||||||
inputLabelLen int
|
inputLabelLen int
|
||||||
inputLabelOpts labelOpts
|
inputLabelOpts labelOpts
|
||||||
|
headerLabel labelPrinter
|
||||||
|
headerLabelLen int
|
||||||
|
headerLabelOpts labelOpts
|
||||||
pointer string
|
pointer string
|
||||||
pointerLen int
|
pointerLen int
|
||||||
pointerEmpty string
|
pointerEmpty string
|
||||||
@ -307,6 +310,7 @@ type Terminal struct {
|
|||||||
borderShape tui.BorderShape
|
borderShape tui.BorderShape
|
||||||
listBorderShape tui.BorderShape
|
listBorderShape tui.BorderShape
|
||||||
inputBorderShape tui.BorderShape
|
inputBorderShape tui.BorderShape
|
||||||
|
headerBorderShape tui.BorderShape
|
||||||
listLabel labelPrinter
|
listLabel labelPrinter
|
||||||
listLabelLen int
|
listLabelLen int
|
||||||
listLabelOpts labelOpts
|
listLabelOpts labelOpts
|
||||||
@ -317,6 +321,8 @@ type Terminal struct {
|
|||||||
window tui.Window
|
window tui.Window
|
||||||
inputWindow tui.Window
|
inputWindow tui.Window
|
||||||
inputBorder tui.Window
|
inputBorder tui.Window
|
||||||
|
headerWindow tui.Window
|
||||||
|
headerBorder tui.Window
|
||||||
wborder tui.Window
|
wborder tui.Window
|
||||||
pborder tui.Window
|
pborder tui.Window
|
||||||
pwindow tui.Window
|
pwindow tui.Window
|
||||||
@ -406,6 +412,7 @@ const (
|
|||||||
reqFullRedraw
|
reqFullRedraw
|
||||||
reqResize
|
reqResize
|
||||||
reqRedrawInputLabel
|
reqRedrawInputLabel
|
||||||
|
reqRedrawHeaderLabel
|
||||||
reqRedrawListLabel
|
reqRedrawListLabel
|
||||||
reqRedrawBorderLabel
|
reqRedrawBorderLabel
|
||||||
reqRedrawPreviewLabel
|
reqRedrawPreviewLabel
|
||||||
@ -450,6 +457,7 @@ const (
|
|||||||
actChangeListLabel
|
actChangeListLabel
|
||||||
actChangeInputLabel
|
actChangeInputLabel
|
||||||
actChangeHeader
|
actChangeHeader
|
||||||
|
actChangeHeaderLabel
|
||||||
actChangeMulti
|
actChangeMulti
|
||||||
actChangePreviewLabel
|
actChangePreviewLabel
|
||||||
actChangePrompt
|
actChangePrompt
|
||||||
@ -512,6 +520,7 @@ const (
|
|||||||
actTransformListLabel
|
actTransformListLabel
|
||||||
actTransformInputLabel
|
actTransformInputLabel
|
||||||
actTransformHeader
|
actTransformHeader
|
||||||
|
actTransformHeaderLabel
|
||||||
actTransformPreviewLabel
|
actTransformPreviewLabel
|
||||||
actTransformPrompt
|
actTransformPrompt
|
||||||
actTransformQuery
|
actTransformQuery
|
||||||
@ -847,6 +856,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
|
|||||||
borderShape: opts.BorderShape,
|
borderShape: opts.BorderShape,
|
||||||
listBorderShape: opts.ListBorderShape,
|
listBorderShape: opts.ListBorderShape,
|
||||||
inputBorderShape: opts.InputBorderShape,
|
inputBorderShape: opts.InputBorderShape,
|
||||||
|
headerBorderShape: opts.HeaderBorderShape,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
listLabel: nil,
|
listLabel: nil,
|
||||||
listLabelOpts: opts.ListLabel,
|
listLabelOpts: opts.ListLabel,
|
||||||
@ -856,6 +866,8 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
|
|||||||
previewLabelOpts: opts.PreviewLabel,
|
previewLabelOpts: opts.PreviewLabel,
|
||||||
inputLabel: nil,
|
inputLabel: nil,
|
||||||
inputLabelOpts: opts.InputLabel,
|
inputLabelOpts: opts.InputLabel,
|
||||||
|
headerLabel: nil,
|
||||||
|
headerLabelOpts: opts.HeaderLabel,
|
||||||
cleanExit: opts.ClearOnExit,
|
cleanExit: opts.ClearOnExit,
|
||||||
executor: executor,
|
executor: executor,
|
||||||
paused: opts.Phony,
|
paused: opts.Phony,
|
||||||
@ -910,7 +922,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
|
|||||||
lastFocus: minItem.Index()}
|
lastFocus: minItem.Index()}
|
||||||
|
|
||||||
// This should be called before accessing tui.Color*
|
// This should be called before accessing tui.Color*
|
||||||
tui.InitTheme(opts.Theme, renderer.DefaultTheme(), opts.Black)
|
tui.InitTheme(opts.Theme, renderer.DefaultTheme(), opts.Black, opts.InputBorderShape.Visible(), opts.HeaderBorderShape.Visible())
|
||||||
|
|
||||||
t.prompt, t.promptLen = t.parsePrompt(opts.Prompt)
|
t.prompt, t.promptLen = t.parsePrompt(opts.Prompt)
|
||||||
// Pre-calculated empty pointer and marker signs
|
// Pre-calculated empty pointer and marker signs
|
||||||
@ -920,6 +932,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
|
|||||||
t.borderLabel, t.borderLabelLen = t.ansiLabelPrinter(opts.BorderLabel.label, &tui.ColBorderLabel, false)
|
t.borderLabel, t.borderLabelLen = t.ansiLabelPrinter(opts.BorderLabel.label, &tui.ColBorderLabel, false)
|
||||||
t.previewLabel, t.previewLabelLen = t.ansiLabelPrinter(opts.PreviewLabel.label, &tui.ColPreviewLabel, false)
|
t.previewLabel, t.previewLabelLen = t.ansiLabelPrinter(opts.PreviewLabel.label, &tui.ColPreviewLabel, false)
|
||||||
t.inputLabel, t.inputLabelLen = t.ansiLabelPrinter(opts.InputLabel.label, &tui.ColInputLabel, false)
|
t.inputLabel, t.inputLabelLen = t.ansiLabelPrinter(opts.InputLabel.label, &tui.ColInputLabel, false)
|
||||||
|
t.headerLabel, t.headerLabelLen = t.ansiLabelPrinter(opts.HeaderLabel.label, &tui.ColHeaderLabel, false)
|
||||||
|
|
||||||
// Disable separator by default if input border is set
|
// Disable separator by default if input border is set
|
||||||
if opts.Separator == nil && !t.inputBorderShape.Visible() || opts.Separator != nil && len(*opts.Separator) > 0 {
|
if opts.Separator == nil && !t.inputBorderShape.Visible() || opts.Separator != nil && len(*opts.Separator) > 0 {
|
||||||
@ -1064,6 +1077,13 @@ func (t *Terminal) visibleHeaderLines() int {
|
|||||||
return len(t.header0) + t.headerLines
|
return len(t.header0) + t.headerLines
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Terminal) visibleHeaderLinesInList() int {
|
||||||
|
if t.headerWindow != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return t.visibleHeaderLines()
|
||||||
|
}
|
||||||
|
|
||||||
// Extra number of lines needed to display fzf
|
// Extra number of lines needed to display fzf
|
||||||
func (t *Terminal) extraLines() int {
|
func (t *Terminal) extraLines() int {
|
||||||
extra := t.visibleHeaderLines() + 1
|
extra := t.visibleHeaderLines() + 1
|
||||||
@ -1148,10 +1168,10 @@ func (t *Terminal) ansiLabelPrinter(str string, color *tui.ColorPair, fill bool)
|
|||||||
|
|
||||||
// Temporarily switch 'window' so that we can use the existing windows with
|
// Temporarily switch 'window' so that we can use the existing windows with
|
||||||
// a different window
|
// a different window
|
||||||
func (t *Terminal) withInputWindow(f func()) {
|
func (t *Terminal) withWindow(w tui.Window, f func()) {
|
||||||
prevWindow := t.window
|
prevWindow := t.window
|
||||||
if t.inputWindow != nil {
|
if w != nil {
|
||||||
t.window = t.inputWindow
|
t.window = w
|
||||||
}
|
}
|
||||||
f()
|
f()
|
||||||
t.window = prevWindow
|
t.window = prevWindow
|
||||||
@ -1184,7 +1204,7 @@ func (t *Terminal) parsePrompt(prompt string) (func(), int) {
|
|||||||
output := func() {
|
output := func() {
|
||||||
wrap := t.wrap
|
wrap := t.wrap
|
||||||
t.wrap = false
|
t.wrap = false
|
||||||
t.withInputWindow(func() {
|
t.withWindow(t.inputWindow, func() {
|
||||||
line := t.promptLine()
|
line := t.promptLine()
|
||||||
t.printHighlighted(
|
t.printHighlighted(
|
||||||
Result{item: item}, tui.ColPrompt, tui.ColPrompt, false, false, line, line, true, nil, nil)
|
Result{item: item}, tui.ColPrompt, tui.ColPrompt, false, false, line, line, true, nil, nil)
|
||||||
@ -1605,6 +1625,12 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
|
|||||||
if t.wborder != nil {
|
if t.wborder != nil {
|
||||||
t.wborder = nil
|
t.wborder = nil
|
||||||
}
|
}
|
||||||
|
if t.headerWindow != nil {
|
||||||
|
t.headerWindow = nil
|
||||||
|
}
|
||||||
|
if t.headerBorder != nil {
|
||||||
|
t.headerBorder = nil
|
||||||
|
}
|
||||||
if t.inputWindow != nil {
|
if t.inputWindow != nil {
|
||||||
t.inputWindow = nil
|
t.inputWindow = nil
|
||||||
}
|
}
|
||||||
@ -1651,26 +1677,42 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
|
|||||||
height -= paddingInt[0] + paddingInt[2]
|
height -= paddingInt[0] + paddingInt[2]
|
||||||
|
|
||||||
// Adjust position and size of the list window if input border is set
|
// Adjust position and size of the list window if input border is set
|
||||||
inputWindowHeight := 0
|
|
||||||
inputBorderHeight := 0
|
inputBorderHeight := 0
|
||||||
|
availableLines := height
|
||||||
shift := 0
|
shift := 0
|
||||||
shrink := 0
|
shrink := 0
|
||||||
hasInputWindow := t.inputBorderShape.Visible()
|
hasInputWindow := t.inputBorderShape.Visible() || t.headerBorderShape.Visible()
|
||||||
if hasInputWindow {
|
if hasInputWindow {
|
||||||
inputWindowHeight = 2
|
inputWindowHeight := 2
|
||||||
if t.noSeparatorLine() {
|
if t.noSeparatorLine() {
|
||||||
inputWindowHeight--
|
inputWindowHeight--
|
||||||
}
|
}
|
||||||
inputBorderHeight = borderLines(t.inputBorderShape) + inputWindowHeight
|
inputBorderHeight = util.Min(availableLines, borderLines(t.inputBorderShape)+inputWindowHeight)
|
||||||
if t.layout == layoutReverse {
|
if t.layout == layoutReverse {
|
||||||
shift = inputBorderHeight
|
shift = inputBorderHeight
|
||||||
shrink = inputBorderHeight
|
shrink = inputBorderHeight
|
||||||
} else {
|
} else {
|
||||||
shift = 0
|
|
||||||
shrink = inputBorderHeight
|
shrink = inputBorderHeight
|
||||||
}
|
}
|
||||||
|
availableLines -= inputBorderHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adjust position and size of the list window if header border is set
|
||||||
|
hasHeaderWindow := t.visibleHeaderLines() > 0 && (t.headerBorderShape.Visible() || t.inputBorderShape.Visible())
|
||||||
|
headerBorderHeight := 0
|
||||||
|
if hasHeaderWindow {
|
||||||
|
headerWindowHeight := t.visibleHeaderLines()
|
||||||
|
headerBorderHeight = util.Min(availableLines, borderLines(t.headerBorderShape)+headerWindowHeight)
|
||||||
|
if t.layout == layoutReverse {
|
||||||
|
shift += headerBorderHeight
|
||||||
|
shrink += headerBorderHeight
|
||||||
|
} else {
|
||||||
|
shrink += headerBorderHeight
|
||||||
|
}
|
||||||
|
availableLines -= headerBorderHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up list border
|
||||||
hasListBorder := t.listBorderShape.Visible()
|
hasListBorder := t.listBorderShape.Visible()
|
||||||
innerWidth := width
|
innerWidth := width
|
||||||
innerHeight := height
|
innerHeight := height
|
||||||
@ -1729,8 +1771,6 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
|
|||||||
// Need a column to show scrollbar
|
// Need a column to show scrollbar
|
||||||
pwidth -= 1
|
pwidth -= 1
|
||||||
}
|
}
|
||||||
pwidth = util.Max(0, pwidth)
|
|
||||||
pheight = util.Max(0, pheight)
|
|
||||||
t.pwindow = t.tui.NewWindow(y, x, pwidth, pheight, tui.WindowPreview, noBorder, true)
|
t.pwindow = t.tui.NewWindow(y, x, pwidth, pheight, tui.WindowPreview, noBorder, true)
|
||||||
if !hadPreviewWindow {
|
if !hadPreviewWindow {
|
||||||
t.pwindow.Erase()
|
t.pwindow.Erase()
|
||||||
@ -1760,6 +1800,14 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
|
|||||||
if previewOpts.hidden {
|
if previewOpts.hidden {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maxPreviewLines := availableLines
|
||||||
|
if t.wborder != nil {
|
||||||
|
maxPreviewLines -= t.wborder.Height()
|
||||||
|
} else {
|
||||||
|
maxPreviewLines -= util.Max(0, innerHeight-pheight-shrink)
|
||||||
|
}
|
||||||
|
pheight = util.Min(pheight, maxPreviewLines)
|
||||||
if previewOpts.position == posUp {
|
if previewOpts.position == posUp {
|
||||||
innerBorderFn(marginInt[0]+pheight, marginInt[3], width, height-pheight)
|
innerBorderFn(marginInt[0]+pheight, marginInt[3], width, height-pheight)
|
||||||
t.window = t.tui.NewWindow(
|
t.window = t.tui.NewWindow(
|
||||||
@ -1873,43 +1921,73 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
|
|||||||
innerHeight-shrink, tui.WindowList, noBorder, true)
|
innerHeight-shrink, tui.WindowList, noBorder, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createInnerWindow := func(b tui.Window, shape tui.BorderShape, windowType tui.WindowType) tui.Window {
|
||||||
|
top := b.Top()
|
||||||
|
left := b.Left()
|
||||||
|
if shape.HasTop() {
|
||||||
|
top++
|
||||||
|
}
|
||||||
|
if shape.HasLeft() {
|
||||||
|
left += t.borderWidth + 1
|
||||||
|
}
|
||||||
|
width := b.Width() - borderColumns(shape, t.borderWidth)
|
||||||
|
if shape.HasRight() {
|
||||||
|
width++
|
||||||
|
}
|
||||||
|
height := b.Height() - borderLines(shape)
|
||||||
|
return t.tui.NewWindow(top, left, width, height, windowType, noBorder, true)
|
||||||
|
}
|
||||||
|
|
||||||
// Set up input border
|
// Set up input border
|
||||||
if hasInputWindow {
|
|
||||||
w := t.wborder
|
w := t.wborder
|
||||||
if t.wborder == nil {
|
if t.wborder == nil {
|
||||||
w = t.window
|
w = t.window
|
||||||
}
|
}
|
||||||
|
if hasInputWindow {
|
||||||
|
var btop int
|
||||||
|
if hasHeaderWindow && t.headerFirst {
|
||||||
if t.layout == layoutReverse {
|
if t.layout == layoutReverse {
|
||||||
t.inputBorder = t.tui.NewWindow(
|
btop = w.Top() - inputBorderHeight
|
||||||
w.Top()-shrink,
|
|
||||||
w.Left(),
|
|
||||||
w.Width(),
|
|
||||||
util.Min(shrink, screenHeight), tui.WindowInput, tui.MakeBorderStyle(t.inputBorderShape, t.unicode), true)
|
|
||||||
} else {
|
} else {
|
||||||
|
btop = w.Top() + w.Height()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if t.layout == layoutReverse {
|
||||||
|
btop = w.Top() - shrink
|
||||||
|
} else {
|
||||||
|
btop = w.Top() + w.Height() + headerBorderHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
t.inputBorder = t.tui.NewWindow(
|
t.inputBorder = t.tui.NewWindow(
|
||||||
w.Top()+w.Height(),
|
btop,
|
||||||
w.Left(),
|
w.Left(),
|
||||||
w.Width(),
|
w.Width(),
|
||||||
util.Min(shrink, screenHeight), tui.WindowInput, tui.MakeBorderStyle(t.inputBorderShape, t.unicode), true)
|
inputBorderHeight, tui.WindowInput, tui.MakeBorderStyle(t.inputBorderShape, t.unicode), true)
|
||||||
|
t.inputWindow = createInnerWindow(t.inputBorder, t.inputBorderShape, tui.WindowInput)
|
||||||
}
|
}
|
||||||
top := t.inputBorder.Top()
|
|
||||||
left := t.inputBorder.Left()
|
// Set up header border
|
||||||
if t.inputBorderShape.HasTop() {
|
if hasHeaderWindow {
|
||||||
top++
|
var btop int
|
||||||
|
if hasInputWindow && t.headerFirst {
|
||||||
|
if t.layout == layoutReverse {
|
||||||
|
btop = w.Top() - shrink
|
||||||
|
} else {
|
||||||
|
btop = w.Top() + w.Height() + inputBorderHeight
|
||||||
}
|
}
|
||||||
if t.inputBorderShape.HasLeft() {
|
} else {
|
||||||
left += t.borderWidth + 1
|
if t.layout == layoutReverse {
|
||||||
|
btop = w.Top() - headerBorderHeight
|
||||||
|
} else {
|
||||||
|
btop = w.Top() + w.Height()
|
||||||
}
|
}
|
||||||
width := t.inputBorder.Width() - borderColumns(t.inputBorderShape, t.borderWidth)
|
|
||||||
if t.inputBorderShape.HasRight() {
|
|
||||||
width++
|
|
||||||
}
|
}
|
||||||
t.inputWindow = t.tui.NewWindow(
|
t.headerBorder = t.tui.NewWindow(
|
||||||
top,
|
btop,
|
||||||
left,
|
w.Left(),
|
||||||
width,
|
w.Width(),
|
||||||
t.inputBorder.Height()-borderLines(t.inputBorderShape),
|
headerBorderHeight, tui.WindowHeader, tui.MakeBorderStyle(t.headerBorderShape, t.unicode), true)
|
||||||
tui.WindowInput, noBorder, true)
|
t.headerWindow = createInnerWindow(t.headerBorder, t.headerBorderShape, tui.WindowHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print border label
|
// Print border label
|
||||||
@ -1917,6 +1995,7 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
|
|||||||
t.printLabel(t.border, t.borderLabel, t.borderLabelOpts, t.borderLabelLen, t.borderShape, false)
|
t.printLabel(t.border, t.borderLabel, t.borderLabelOpts, t.borderLabelLen, t.borderShape, false)
|
||||||
t.printLabel(t.pborder, t.previewLabel, t.previewLabelOpts, t.previewLabelLen, t.activePreviewOpts.border, false)
|
t.printLabel(t.pborder, t.previewLabel, t.previewLabelOpts, t.previewLabelLen, t.activePreviewOpts.border, false)
|
||||||
t.printLabel(t.inputBorder, t.inputLabel, t.inputLabelOpts, t.inputLabelLen, t.inputBorderShape, false)
|
t.printLabel(t.inputBorder, t.inputLabel, t.inputLabelOpts, t.inputLabelLen, t.inputBorderShape, false)
|
||||||
|
t.printLabel(t.headerBorder, t.headerLabel, t.headerLabelOpts, t.headerLabelLen, t.headerBorderShape, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) printLabel(window tui.Window, render labelPrinter, opts labelOpts, length int, borderShape tui.BorderShape, redrawBorder bool) {
|
func (t *Terminal) printLabel(window tui.Window, render labelPrinter, opts labelOpts, length int, borderShape tui.BorderShape, redrawBorder bool) {
|
||||||
@ -1960,7 +2039,7 @@ func (t *Terminal) move(y int, x int, clear bool) {
|
|||||||
case layoutDefault:
|
case layoutDefault:
|
||||||
y = h - y - 1
|
y = h - y - 1
|
||||||
case layoutReverseList:
|
case layoutReverseList:
|
||||||
n := 2 + t.visibleHeaderLines()
|
n := 2 + t.visibleHeaderLinesInList()
|
||||||
if t.noSeparatorLine() {
|
if t.noSeparatorLine() {
|
||||||
n--
|
n--
|
||||||
}
|
}
|
||||||
@ -2014,7 +2093,7 @@ func (t *Terminal) promptLine() int {
|
|||||||
if !t.noSeparatorLine() {
|
if !t.noSeparatorLine() {
|
||||||
max--
|
max--
|
||||||
}
|
}
|
||||||
return util.Min(t.visibleHeaderLines(), max)
|
return util.Min(t.visibleHeaderLinesInList(), max)
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@ -2059,9 +2138,7 @@ func (t *Terminal) trimMessage(message string, maxWidth int) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) printInfo() {
|
func (t *Terminal) printInfo() {
|
||||||
t.withInputWindow(func() {
|
t.withWindow(t.inputWindow, func() { t.printInfoImpl() })
|
||||||
t.printInfoImpl()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) printInfoImpl() {
|
func (t *Terminal) printInfoImpl() {
|
||||||
@ -2258,11 +2335,23 @@ func (t *Terminal) printInfoImpl() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) printHeader() {
|
func (t *Terminal) printHeader() {
|
||||||
|
headerLines := t.visibleHeaderLines()
|
||||||
|
if t.headerBorderShape.Visible() && (t.headerWindow == nil && headerLines > 0 || t.headerWindow != nil && headerLines != t.headerWindow.Height()) {
|
||||||
|
t.resizeWindows(false, true)
|
||||||
|
t.printList()
|
||||||
|
t.printPrompt()
|
||||||
|
t.printInfo()
|
||||||
|
t.printPreview()
|
||||||
|
}
|
||||||
|
t.withWindow(t.headerWindow, func() { t.printHeaderImpl() })
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Terminal) printHeaderImpl() {
|
||||||
if t.visibleHeaderLines() == 0 {
|
if t.visibleHeaderLines() == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
max := t.window.Height()
|
max := t.window.Height()
|
||||||
if t.inputWindow == nil && t.headerFirst {
|
if t.inputWindow == nil && t.headerWindow == nil && t.headerFirst {
|
||||||
max--
|
max--
|
||||||
if !t.noSeparatorLine() {
|
if !t.noSeparatorLine() {
|
||||||
max--
|
max--
|
||||||
@ -2276,13 +2365,14 @@ func (t *Terminal) printHeader() {
|
|||||||
}
|
}
|
||||||
// Wrapping is not supported for header
|
// Wrapping is not supported for header
|
||||||
wrap := t.wrap
|
wrap := t.wrap
|
||||||
|
indent := strings.Repeat(" ", t.pointerLen+t.markerLen)
|
||||||
t.wrap = false
|
t.wrap = false
|
||||||
for idx, lineStr := range append(append([]string{}, t.header0...), t.header...) {
|
for idx, lineStr := range append(append([]string{}, t.header0...), t.header...) {
|
||||||
line := idx
|
line := idx
|
||||||
if needReverse && idx < len(t.header0) {
|
if needReverse && idx < len(t.header0) {
|
||||||
line = len(t.header0) - idx - 1
|
line = len(t.header0) - idx - 1
|
||||||
}
|
}
|
||||||
if t.inputWindow == nil && !t.headerFirst {
|
if t.inputWindow == nil && t.headerWindow == nil && !t.headerFirst {
|
||||||
line++
|
line++
|
||||||
if !t.noSeparatorLine() {
|
if !t.noSeparatorLine() {
|
||||||
line++
|
line++
|
||||||
@ -2299,7 +2389,7 @@ func (t *Terminal) printHeader() {
|
|||||||
|
|
||||||
t.printHighlighted(Result{item: item},
|
t.printHighlighted(Result{item: item},
|
||||||
tui.ColHeader, tui.ColHeader, false, false, line, line, true,
|
tui.ColHeader, tui.ColHeader, false, false, line, line, true,
|
||||||
func(markerClass) { t.window.Print(strings.Repeat(" ", t.pointerLen+t.markerLen)) }, nil)
|
func(markerClass) { t.window.Print(indent) }, nil)
|
||||||
}
|
}
|
||||||
t.wrap = wrap
|
t.wrap = wrap
|
||||||
}
|
}
|
||||||
@ -2327,7 +2417,7 @@ func (t *Terminal) printList() {
|
|||||||
count := t.merger.Length() - t.offset
|
count := t.merger.Length() - t.offset
|
||||||
|
|
||||||
// Start line
|
// Start line
|
||||||
startLine := t.promptLines() + t.visibleHeaderLines()
|
startLine := t.promptLines() + t.visibleHeaderLinesInList()
|
||||||
maxy += startLine
|
maxy += startLine
|
||||||
|
|
||||||
barRange := [2]int{startLine + barStart, startLine + barStart + barLength}
|
barRange := [2]int{startLine + barStart, startLine + barStart + barLength}
|
||||||
@ -3187,7 +3277,7 @@ func (t *Terminal) printAll() {
|
|||||||
func (t *Terminal) flush() {
|
func (t *Terminal) flush() {
|
||||||
t.placeCursor()
|
t.placeCursor()
|
||||||
if !t.suppress {
|
if !t.suppress {
|
||||||
windows := make([]tui.Window, 0, 7)
|
windows := make([]tui.Window, 0, 9)
|
||||||
if t.border != nil {
|
if t.border != nil {
|
||||||
windows = append(windows, t.border)
|
windows = append(windows, t.border)
|
||||||
}
|
}
|
||||||
@ -3203,6 +3293,12 @@ func (t *Terminal) flush() {
|
|||||||
if t.window != nil {
|
if t.window != nil {
|
||||||
windows = append(windows, t.window)
|
windows = append(windows, t.window)
|
||||||
}
|
}
|
||||||
|
if t.headerBorder != nil {
|
||||||
|
windows = append(windows, t.headerBorder)
|
||||||
|
}
|
||||||
|
if t.headerWindow != nil {
|
||||||
|
windows = append(windows, t.headerWindow)
|
||||||
|
}
|
||||||
if t.inputBorder != nil {
|
if t.inputBorder != nil {
|
||||||
windows = append(windows, t.inputBorder)
|
windows = append(windows, t.inputBorder)
|
||||||
}
|
}
|
||||||
@ -4110,6 +4206,8 @@ func (t *Terminal) Loop() error {
|
|||||||
}
|
}
|
||||||
case reqRedrawInputLabel:
|
case reqRedrawInputLabel:
|
||||||
t.printLabel(t.inputBorder, t.inputLabel, t.inputLabelOpts, t.inputLabelLen, t.inputBorderShape, true)
|
t.printLabel(t.inputBorder, t.inputLabel, t.inputLabelOpts, t.inputLabelLen, t.inputBorderShape, true)
|
||||||
|
case reqRedrawHeaderLabel:
|
||||||
|
t.printLabel(t.headerBorder, t.headerLabel, t.headerLabelOpts, t.headerLabelLen, t.headerBorderShape, true)
|
||||||
case reqRedrawListLabel:
|
case reqRedrawListLabel:
|
||||||
t.printLabel(t.wborder, t.listLabel, t.listLabelOpts, t.listLabelLen, t.listBorderShape, true)
|
t.printLabel(t.wborder, t.listLabel, t.listLabelOpts, t.listLabelLen, t.listBorderShape, true)
|
||||||
case reqRedrawBorderLabel:
|
case reqRedrawBorderLabel:
|
||||||
@ -4493,6 +4591,12 @@ func (t *Terminal) Loop() error {
|
|||||||
} else {
|
} else {
|
||||||
req(reqHeader)
|
req(reqHeader)
|
||||||
}
|
}
|
||||||
|
case actChangeHeaderLabel:
|
||||||
|
t.headerLabelOpts.label = a.a
|
||||||
|
if t.headerBorder != nil {
|
||||||
|
t.headerLabel, t.headerLabelLen = t.ansiLabelPrinter(a.a, &tui.ColHeaderLabel, false)
|
||||||
|
req(reqRedrawHeaderLabel)
|
||||||
|
}
|
||||||
case actChangeInputLabel:
|
case actChangeInputLabel:
|
||||||
t.inputLabelOpts.label = a.a
|
t.inputLabelOpts.label = a.a
|
||||||
if t.inputBorder != nil {
|
if t.inputBorder != nil {
|
||||||
@ -4522,6 +4626,13 @@ func (t *Terminal) Loop() error {
|
|||||||
if actions, err := parseSingleActionList(strings.Trim(body, "\r\n")); err == nil {
|
if actions, err := parseSingleActionList(strings.Trim(body, "\r\n")); err == nil {
|
||||||
return doActions(actions)
|
return doActions(actions)
|
||||||
}
|
}
|
||||||
|
case actTransformHeaderLabel:
|
||||||
|
label := t.executeCommand(a.a, false, true, true, true, "")
|
||||||
|
t.headerLabelOpts.label = label
|
||||||
|
if t.headerBorder != nil {
|
||||||
|
t.headerLabel, t.headerLabelLen = t.ansiLabelPrinter(label, &tui.ColHeaderLabel, false)
|
||||||
|
req(reqRedrawHeaderLabel)
|
||||||
|
}
|
||||||
case actTransformInputLabel:
|
case actTransformInputLabel:
|
||||||
label := t.executeCommand(a.a, false, true, true, true, "")
|
label := t.executeCommand(a.a, false, true, true, true, "")
|
||||||
t.inputLabelOpts.label = label
|
t.inputLabelOpts.label = label
|
||||||
@ -5028,25 +5139,25 @@ func (t *Terminal) Loop() error {
|
|||||||
case posUp:
|
case posUp:
|
||||||
if t.pborder.Enclose(my, mx) && my == t.pborder.Top()+t.pborder.Height()-1 {
|
if t.pborder.Enclose(my, mx) && my == t.pborder.Top()+t.pborder.Height()-1 {
|
||||||
pborderDragging = 0
|
pborderDragging = 0
|
||||||
} else if t.listBorderShape.HasTop() && t.wborder.Enclose(my, mx) && my == t.wborder.Top() {
|
} else if t.listBorderShape.HasTop() && t.pborder.EncloseX(mx) && my == t.wborder.Top() {
|
||||||
pborderDragging = 1
|
pborderDragging = 1
|
||||||
}
|
}
|
||||||
case posDown:
|
case posDown:
|
||||||
if t.pborder.Enclose(my, mx) && my == t.pborder.Top() {
|
if t.pborder.Enclose(my, mx) && my == t.pborder.Top() {
|
||||||
pborderDragging = 0
|
pborderDragging = 0
|
||||||
} else if t.listBorderShape.HasBottom() && t.wborder.Enclose(my, mx) && my == t.wborder.Top()+t.wborder.Height()-1 {
|
} else if t.listBorderShape.HasBottom() && t.pborder.EncloseX(mx) && my == t.wborder.Top()+t.wborder.Height()-1 {
|
||||||
pborderDragging = 1
|
pborderDragging = 1
|
||||||
}
|
}
|
||||||
case posLeft:
|
case posLeft:
|
||||||
if t.pborder.Enclose(my, mx) && mx == t.pborder.Left()+t.pborder.Width()-1 {
|
if t.pborder.Enclose(my, mx) && mx == t.pborder.Left()+t.pborder.Width()-1 {
|
||||||
pborderDragging = 0
|
pborderDragging = 0
|
||||||
} else if t.listBorderShape.HasLeft() && t.wborder.Enclose(my, mx) && mx == t.wborder.Left() {
|
} else if t.listBorderShape.HasLeft() && t.pborder.EncloseY(my) && mx == t.wborder.Left() {
|
||||||
pborderDragging = 1
|
pborderDragging = 1
|
||||||
}
|
}
|
||||||
case posRight:
|
case posRight:
|
||||||
if t.pborder.Enclose(my, mx) && mx == t.pborder.Left() {
|
if t.pborder.Enclose(my, mx) && mx == t.pborder.Left() {
|
||||||
pborderDragging = 0
|
pborderDragging = 0
|
||||||
} else if t.listBorderShape.HasRight() && t.wborder.Enclose(my, mx) && mx == t.wborder.Left()+t.wborder.Width()-1 {
|
} else if t.listBorderShape.HasRight() && t.pborder.EncloseY(my) && mx == t.wborder.Left()+t.wborder.Width()-1 {
|
||||||
pborderDragging = 1
|
pborderDragging = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5103,6 +5214,20 @@ func (t *Terminal) Loop() error {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inside the header window
|
||||||
|
// TODO: Should we trigger this on mouse up instead?
|
||||||
|
// Should we still trigger it when the position has changed from the down event?
|
||||||
|
if t.headerVisible && t.headerWindow != nil && t.headerWindow.Enclose(my, mx) {
|
||||||
|
mx -= t.headerWindow.Left() + t.pointerLen + t.markerLen
|
||||||
|
my -= t.headerWindow.Top()
|
||||||
|
if mx < 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
t.clickHeaderLine = my + 1
|
||||||
|
t.clickHeaderColumn = mx + 1
|
||||||
|
return doActions(actionsFor(tui.ClickHeader))
|
||||||
|
}
|
||||||
|
|
||||||
// Ignored
|
// Ignored
|
||||||
if !t.window.Enclose(my, mx) && !barDragging {
|
if !t.window.Enclose(my, mx) && !barDragging {
|
||||||
break
|
break
|
||||||
@ -5111,7 +5236,7 @@ func (t *Terminal) Loop() error {
|
|||||||
// Translate coordinates
|
// Translate coordinates
|
||||||
mx -= t.window.Left()
|
mx -= t.window.Left()
|
||||||
my -= t.window.Top()
|
my -= t.window.Top()
|
||||||
min := t.promptLines() + t.visibleHeaderLines()
|
min := t.promptLines() + t.visibleHeaderLinesInList()
|
||||||
h := t.window.Height()
|
h := t.window.Height()
|
||||||
switch t.layout {
|
switch t.layout {
|
||||||
case layoutDefault:
|
case layoutDefault:
|
||||||
@ -5180,9 +5305,10 @@ func (t *Terminal) Loop() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return doActions(actionsFor(evt))
|
return doActions(actionsFor(evt))
|
||||||
} else if t.headerVisible {
|
} else if t.headerVisible && t.headerWindow == nil {
|
||||||
// Header
|
// Header
|
||||||
numLines := t.visibleHeaderLines()
|
// TODO: Should we trigger this on mouse up instead?
|
||||||
|
numLines := t.visibleHeaderLinesInList()
|
||||||
lineOffset := 0
|
lineOffset := 0
|
||||||
if t.inputWindow == nil && !t.headerFirst {
|
if t.inputWindow == nil && !t.headerFirst {
|
||||||
// offset for info line
|
// offset for info line
|
||||||
@ -5193,7 +5319,7 @@ func (t *Terminal) Loop() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
my -= lineOffset
|
my -= lineOffset
|
||||||
mx -= 2 // offset gutter
|
mx -= t.pointerLen + t.markerLen
|
||||||
if my >= 0 && my < numLines && mx >= 0 {
|
if my >= 0 && my < numLines && mx >= 0 {
|
||||||
if t.layout == layoutReverse {
|
if t.layout == layoutReverse {
|
||||||
t.clickHeaderLine = my + 1
|
t.clickHeaderLine = my + 1
|
||||||
@ -5525,7 +5651,7 @@ func (t *Terminal) promptLines() int {
|
|||||||
|
|
||||||
// Number of item lines in the list window
|
// Number of item lines in the list window
|
||||||
func (t *Terminal) maxItems() int {
|
func (t *Terminal) maxItems() int {
|
||||||
max := t.window.Height() - t.visibleHeaderLines() - t.promptLines()
|
max := t.window.Height() - t.visibleHeaderLinesInList() - t.promptLines()
|
||||||
return util.Max(max, 0)
|
return util.Max(max, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,6 +804,9 @@ func (r *LightRenderer) NewWindow(top int, left int, width int, height int, wind
|
|||||||
case WindowInput:
|
case WindowInput:
|
||||||
w.fg = r.theme.Input.Color
|
w.fg = r.theme.Input.Color
|
||||||
w.bg = r.theme.InputBg.Color
|
w.bg = r.theme.InputBg.Color
|
||||||
|
case WindowHeader:
|
||||||
|
w.fg = r.theme.Header.Color
|
||||||
|
w.bg = r.theme.HeaderBg.Color
|
||||||
case WindowPreview:
|
case WindowPreview:
|
||||||
w.fg = r.theme.PreviewFg.Color
|
w.fg = r.theme.PreviewFg.Color
|
||||||
w.bg = r.theme.PreviewBg.Color
|
w.bg = r.theme.PreviewBg.Color
|
||||||
@ -862,6 +865,8 @@ func (w *LightWindow) drawBorderHorizontal(top, bottom bool) {
|
|||||||
color = ColListBorder
|
color = ColListBorder
|
||||||
case WindowInput:
|
case WindowInput:
|
||||||
color = ColInputBorder
|
color = ColInputBorder
|
||||||
|
case WindowHeader:
|
||||||
|
color = ColHeaderBorder
|
||||||
case WindowPreview:
|
case WindowPreview:
|
||||||
color = ColPreviewBorder
|
color = ColPreviewBorder
|
||||||
}
|
}
|
||||||
@ -885,6 +890,8 @@ func (w *LightWindow) drawBorderVertical(left, right bool) {
|
|||||||
color = ColListBorder
|
color = ColListBorder
|
||||||
case WindowInput:
|
case WindowInput:
|
||||||
color = ColInputBorder
|
color = ColInputBorder
|
||||||
|
case WindowHeader:
|
||||||
|
color = ColHeaderBorder
|
||||||
case WindowPreview:
|
case WindowPreview:
|
||||||
color = ColPreviewBorder
|
color = ColPreviewBorder
|
||||||
}
|
}
|
||||||
@ -910,6 +917,8 @@ func (w *LightWindow) drawBorderAround(onlyHorizontal bool) {
|
|||||||
color = ColListBorder
|
color = ColListBorder
|
||||||
case WindowInput:
|
case WindowInput:
|
||||||
color = ColInputBorder
|
color = ColInputBorder
|
||||||
|
case WindowHeader:
|
||||||
|
color = ColHeaderBorder
|
||||||
case WindowPreview:
|
case WindowPreview:
|
||||||
color = ColPreviewBorder
|
color = ColPreviewBorder
|
||||||
}
|
}
|
||||||
@ -970,9 +979,16 @@ func (w *LightWindow) Y() int {
|
|||||||
return w.posy
|
return w.posy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *LightWindow) EncloseX(x int) bool {
|
||||||
|
return x >= w.left && x < (w.left+w.width)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *LightWindow) EncloseY(y int) bool {
|
||||||
|
return y >= w.top && y < (w.top+w.height)
|
||||||
|
}
|
||||||
|
|
||||||
func (w *LightWindow) Enclose(y int, x int) bool {
|
func (w *LightWindow) Enclose(y int, x int) bool {
|
||||||
return x >= w.left && x < (w.left+w.width) &&
|
return w.EncloseX(x) && w.EncloseY(y)
|
||||||
y >= w.top && y < (w.top+w.height)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *LightWindow) Move(y int, x int) {
|
func (w *LightWindow) Move(y int, x int) {
|
||||||
|
@ -557,6 +557,8 @@ func (r *FullscreenRenderer) NewWindow(top int, left int, width int, height int,
|
|||||||
switch windowType {
|
switch windowType {
|
||||||
case WindowList:
|
case WindowList:
|
||||||
normal = ColListBorder
|
normal = ColListBorder
|
||||||
|
case WindowHeader:
|
||||||
|
normal = ColHeaderBorder
|
||||||
case WindowInput:
|
case WindowInput:
|
||||||
normal = ColInputBorder
|
normal = ColInputBorder
|
||||||
case WindowPreview:
|
case WindowPreview:
|
||||||
@ -593,9 +595,16 @@ func (w *TcellWindow) EraseMaybe() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *TcellWindow) EncloseX(x int) bool {
|
||||||
|
return x >= w.left && x < (w.left+w.width)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *TcellWindow) EncloseY(y int) bool {
|
||||||
|
return y >= w.top && y < (w.top+w.height)
|
||||||
|
}
|
||||||
|
|
||||||
func (w *TcellWindow) Enclose(y int, x int) bool {
|
func (w *TcellWindow) Enclose(y int, x int) bool {
|
||||||
return x >= w.left && x < (w.left+w.width) &&
|
return w.EncloseX(x) && w.EncloseY(y)
|
||||||
y >= w.top && y < (w.top+w.height)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *TcellWindow) Move(y int, x int) {
|
func (w *TcellWindow) Move(y int, x int) {
|
||||||
@ -792,6 +801,8 @@ func (w *TcellWindow) drawBorder(onlyHorizontal bool) {
|
|||||||
style = ColBorder.style()
|
style = ColBorder.style()
|
||||||
case WindowList:
|
case WindowList:
|
||||||
style = ColListBorder.style()
|
style = ColListBorder.style()
|
||||||
|
case WindowHeader:
|
||||||
|
style = ColHeaderBorder.style()
|
||||||
case WindowInput:
|
case WindowInput:
|
||||||
style = ColInputBorder.style()
|
style = ColInputBorder.style()
|
||||||
case WindowPreview:
|
case WindowPreview:
|
||||||
|
@ -324,6 +324,9 @@ type ColorTheme struct {
|
|||||||
Cursor ColorAttr
|
Cursor ColorAttr
|
||||||
Marker ColorAttr
|
Marker ColorAttr
|
||||||
Header ColorAttr
|
Header ColorAttr
|
||||||
|
HeaderBg ColorAttr
|
||||||
|
HeaderBorder ColorAttr
|
||||||
|
HeaderLabel ColorAttr
|
||||||
Separator ColorAttr
|
Separator ColorAttr
|
||||||
Scrollbar ColorAttr
|
Scrollbar ColorAttr
|
||||||
Border ColorAttr
|
Border ColorAttr
|
||||||
@ -543,6 +546,7 @@ const (
|
|||||||
WindowList
|
WindowList
|
||||||
WindowPreview
|
WindowPreview
|
||||||
WindowInput
|
WindowInput
|
||||||
|
WindowHeader
|
||||||
)
|
)
|
||||||
|
|
||||||
type Renderer interface {
|
type Renderer interface {
|
||||||
@ -583,6 +587,8 @@ type Window interface {
|
|||||||
|
|
||||||
X() int
|
X() int
|
||||||
Y() int
|
Y() int
|
||||||
|
EncloseX(x int) bool
|
||||||
|
EncloseY(y int) bool
|
||||||
Enclose(y int, x int) bool
|
Enclose(y int, x int) bool
|
||||||
|
|
||||||
Move(y int, x int)
|
Move(y int, x int)
|
||||||
@ -639,6 +645,8 @@ var (
|
|||||||
ColSpinner ColorPair
|
ColSpinner ColorPair
|
||||||
ColInfo ColorPair
|
ColInfo ColorPair
|
||||||
ColHeader ColorPair
|
ColHeader ColorPair
|
||||||
|
ColHeaderBorder ColorPair
|
||||||
|
ColHeaderLabel ColorPair
|
||||||
ColSeparator ColorPair
|
ColSeparator ColorPair
|
||||||
ColScrollbar ColorPair
|
ColScrollbar ColorPair
|
||||||
ColBorder ColorPair
|
ColBorder ColorPair
|
||||||
@ -691,6 +699,9 @@ func EmptyTheme() *ColorTheme {
|
|||||||
InputBg: ColorAttr{colUndefined, AttrUndefined},
|
InputBg: ColorAttr{colUndefined, AttrUndefined},
|
||||||
InputBorder: ColorAttr{colUndefined, AttrUndefined},
|
InputBorder: ColorAttr{colUndefined, AttrUndefined},
|
||||||
InputLabel: ColorAttr{colUndefined, AttrUndefined},
|
InputLabel: ColorAttr{colUndefined, AttrUndefined},
|
||||||
|
HeaderBg: ColorAttr{colUndefined, AttrUndefined},
|
||||||
|
HeaderBorder: ColorAttr{colUndefined, AttrUndefined},
|
||||||
|
HeaderLabel: ColorAttr{colUndefined, AttrUndefined},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,6 +742,9 @@ func NoColorTheme() *ColorTheme {
|
|||||||
InputBg: ColorAttr{colDefault, AttrUndefined},
|
InputBg: ColorAttr{colDefault, AttrUndefined},
|
||||||
InputBorder: ColorAttr{colDefault, AttrUndefined},
|
InputBorder: ColorAttr{colDefault, AttrUndefined},
|
||||||
InputLabel: ColorAttr{colDefault, AttrUndefined},
|
InputLabel: ColorAttr{colDefault, AttrUndefined},
|
||||||
|
HeaderBg: ColorAttr{colDefault, AttrUndefined},
|
||||||
|
HeaderBorder: ColorAttr{colDefault, AttrUndefined},
|
||||||
|
HeaderLabel: ColorAttr{colDefault, AttrUndefined},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -845,10 +859,13 @@ func init() {
|
|||||||
InputBg: ColorAttr{colUndefined, AttrUndefined},
|
InputBg: ColorAttr{colUndefined, AttrUndefined},
|
||||||
InputBorder: ColorAttr{colUndefined, AttrUndefined},
|
InputBorder: ColorAttr{colUndefined, AttrUndefined},
|
||||||
InputLabel: ColorAttr{colUndefined, AttrUndefined},
|
InputLabel: ColorAttr{colUndefined, AttrUndefined},
|
||||||
|
HeaderBg: ColorAttr{colUndefined, AttrUndefined},
|
||||||
|
HeaderBorder: ColorAttr{colUndefined, AttrUndefined},
|
||||||
|
HeaderLabel: ColorAttr{colUndefined, AttrUndefined},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitTheme(theme *ColorTheme, baseTheme *ColorTheme, forceBlack bool) {
|
func InitTheme(theme *ColorTheme, baseTheme *ColorTheme, forceBlack bool, hasInputWindow bool, hasHeaderWindow bool) {
|
||||||
if forceBlack {
|
if forceBlack {
|
||||||
theme.Bg = ColorAttr{colBlack, AttrUndefined}
|
theme.Bg = ColorAttr{colBlack, AttrUndefined}
|
||||||
}
|
}
|
||||||
@ -896,9 +913,22 @@ func InitTheme(theme *ColorTheme, baseTheme *ColorTheme, forceBlack bool) {
|
|||||||
theme.Separator = o(theme.ListBorder, theme.Separator)
|
theme.Separator = o(theme.ListBorder, theme.Separator)
|
||||||
theme.Scrollbar = o(theme.ListBorder, theme.Scrollbar)
|
theme.Scrollbar = o(theme.ListBorder, theme.Scrollbar)
|
||||||
theme.PreviewScrollbar = o(theme.PreviewBorder, theme.PreviewScrollbar)
|
theme.PreviewScrollbar = o(theme.PreviewBorder, theme.PreviewScrollbar)
|
||||||
theme.InputBg = o(theme.Bg, o(theme.ListBg, theme.InputBg))
|
if hasInputWindow {
|
||||||
|
theme.InputBg = o(theme.Bg, theme.InputBg)
|
||||||
|
} else {
|
||||||
|
// We shouldn't use input-bg if there's no separate input window
|
||||||
|
// e.g. fzf --color 'list-bg:green,input-bg:red' --no-input-border
|
||||||
|
theme.InputBg = o(theme.Bg, theme.ListBg)
|
||||||
|
}
|
||||||
theme.InputBorder = o(theme.Border, theme.InputBorder)
|
theme.InputBorder = o(theme.Border, theme.InputBorder)
|
||||||
theme.InputLabel = o(theme.BorderLabel, theme.InputLabel)
|
theme.InputLabel = o(theme.BorderLabel, theme.InputLabel)
|
||||||
|
if hasHeaderWindow {
|
||||||
|
theme.HeaderBg = o(theme.Bg, theme.HeaderBg)
|
||||||
|
} else {
|
||||||
|
theme.HeaderBg = o(theme.Bg, theme.ListBg)
|
||||||
|
}
|
||||||
|
theme.HeaderBorder = o(theme.Border, theme.HeaderBorder)
|
||||||
|
theme.HeaderLabel = o(theme.BorderLabel, theme.HeaderLabel)
|
||||||
|
|
||||||
initPalette(theme)
|
initPalette(theme)
|
||||||
}
|
}
|
||||||
@ -935,7 +965,6 @@ func initPalette(theme *ColorTheme) {
|
|||||||
ColCurrentSelectedEmpty = pair(blank, theme.DarkBg)
|
ColCurrentSelectedEmpty = pair(blank, theme.DarkBg)
|
||||||
ColSpinner = pair(theme.Spinner, theme.InputBg)
|
ColSpinner = pair(theme.Spinner, theme.InputBg)
|
||||||
ColInfo = pair(theme.Info, theme.InputBg)
|
ColInfo = pair(theme.Info, theme.InputBg)
|
||||||
ColHeader = pair(theme.Header, theme.ListBg)
|
|
||||||
ColSeparator = pair(theme.Separator, theme.InputBg)
|
ColSeparator = pair(theme.Separator, theme.InputBg)
|
||||||
ColScrollbar = pair(theme.Scrollbar, theme.ListBg)
|
ColScrollbar = pair(theme.Scrollbar, theme.ListBg)
|
||||||
ColBorder = pair(theme.Border, theme.Bg)
|
ColBorder = pair(theme.Border, theme.Bg)
|
||||||
@ -949,6 +978,9 @@ func initPalette(theme *ColorTheme) {
|
|||||||
ColListBorder = pair(theme.ListBorder, theme.ListBg)
|
ColListBorder = pair(theme.ListBorder, theme.ListBg)
|
||||||
ColInputBorder = pair(theme.InputBorder, theme.InputBg)
|
ColInputBorder = pair(theme.InputBorder, theme.InputBg)
|
||||||
ColInputLabel = pair(theme.InputLabel, theme.InputBg)
|
ColInputLabel = pair(theme.InputLabel, theme.InputBg)
|
||||||
|
ColHeader = pair(theme.Header, theme.HeaderBg)
|
||||||
|
ColHeaderBorder = pair(theme.HeaderBorder, theme.HeaderBg)
|
||||||
|
ColHeaderLabel = pair(theme.HeaderLabel, theme.HeaderBg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runeWidth(r rune) int {
|
func runeWidth(r rune) int {
|
||||||
|
207
test/test_go.rb
207
test/test_go.rb
@ -3485,6 +3485,24 @@ class TestGoFZF < TestBase
|
|||||||
tmux.until { assert_block(block, _1) }
|
tmux.until { assert_block(block, _1) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_input_border_and_label_header_first
|
||||||
|
tmux.send_keys %(seq 100 | #{FZF} --border rounded --input-border bold --input-label input --input-label-pos 2 --header-lines 3 --query 1 --padding 1,2 --header-first), :Enter
|
||||||
|
block = <<~BLOCK
|
||||||
|
│ 11
|
||||||
|
│ > 10
|
||||||
|
│ ┏input━━━━━
|
||||||
|
│ ┃ 19/97
|
||||||
|
│ ┃ > 1
|
||||||
|
│ ┗━━━━━━━━━━
|
||||||
|
│ 3
|
||||||
|
│ 2
|
||||||
|
│ 1
|
||||||
|
│
|
||||||
|
╰──────────────
|
||||||
|
BLOCK
|
||||||
|
tmux.until { assert_block(block, _1) }
|
||||||
|
end
|
||||||
|
|
||||||
def test_list_input_border_and_label
|
def test_list_input_border_and_label
|
||||||
tmux.send_keys %(
|
tmux.send_keys %(
|
||||||
seq 100 | #{FZF} --border rounded --list-border double --input-border bold --list-label-pos 2:bottom --input-label-pos 2 --header-lines 3 --query 1 --padding 1,2 \
|
seq 100 | #{FZF} --border rounded --list-border double --input-border bold --list-label-pos 2:bottom --input-label-pos 2 --header-lines 3 --query 1 --padding 1,2 \
|
||||||
@ -3494,32 +3512,193 @@ class TestGoFZF < TestBase
|
|||||||
block = <<~BLOCK
|
block = <<~BLOCK
|
||||||
│ ║ 11
|
│ ║ 11
|
||||||
│ ║ > 10
|
│ ║ > 10
|
||||||
│ ║ 3
|
│ ╚LIST══════
|
||||||
│ ║ 2
|
│ 3
|
||||||
│ ║ 1
|
│ 2
|
||||||
│ ╚LIST═════
|
│ 1
|
||||||
│ ┏INPUT━━━━
|
│ ┏INPUT━━━━━
|
||||||
│ ┃ 19/97
|
│ ┃ 19/97
|
||||||
│ ┃ > 1
|
│ ┃ > 1
|
||||||
│ ┗━━━━━━━━━
|
│ ┗━━━━━━━━━━
|
||||||
│
|
│
|
||||||
╰─────────────
|
╰──────────────
|
||||||
BLOCK
|
BLOCK
|
||||||
tmux.until { assert_block(block, _1) }
|
tmux.until { assert_block(block, _1) }
|
||||||
tmux.send_keys :Space
|
tmux.send_keys :Space
|
||||||
block = <<~BLOCK
|
block = <<~BLOCK
|
||||||
│ ║ 11
|
│ ║ 11
|
||||||
│ ║ > 10
|
│ ║ > 10
|
||||||
│ ║ 3
|
│ ╚ list ════
|
||||||
│ ║ 2
|
│ 3
|
||||||
│ ║ 1
|
│ 2
|
||||||
│ ╚ list ═══
|
│ 1
|
||||||
│ ┏ input ━━
|
│ ┏ input ━━━
|
||||||
│ ┃ 19/97
|
│ ┃ 19/97
|
||||||
│ ┃ > 1
|
│ ┃ > 1
|
||||||
│ ┗━━━━━━━━━
|
│ ┗━━━━━━━━━━
|
||||||
│
|
│
|
||||||
╰─────────────
|
╰──────────────
|
||||||
|
BLOCK
|
||||||
|
tmux.until { assert_block(block, _1) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_list_input_border_and_label_header_first
|
||||||
|
tmux.send_keys %(
|
||||||
|
seq 100 | #{FZF} --border rounded --list-border double --input-border bold --list-label-pos 2:bottom --input-label-pos 2 --header-lines 3 --query 1 --padding 1,2 \
|
||||||
|
--bind 'start:transform-input-label(echo INPUT)+transform-list-label(echo LIST)' \
|
||||||
|
--bind 'space:change-input-label( input )+change-list-label( list )' --header-first
|
||||||
|
).strip, :Enter
|
||||||
|
block = <<~BLOCK
|
||||||
|
│ ║ 11
|
||||||
|
│ ║ > 10
|
||||||
|
│ ╚LIST══════
|
||||||
|
│ ┏INPUT━━━━━
|
||||||
|
│ ┃ 19/97
|
||||||
|
│ ┃ > 1
|
||||||
|
│ ┗━━━━━━━━━━
|
||||||
|
│ 3
|
||||||
|
│ 2
|
||||||
|
│ 1
|
||||||
|
│
|
||||||
|
╰──────────────
|
||||||
|
BLOCK
|
||||||
|
tmux.until { assert_block(block, _1) }
|
||||||
|
tmux.send_keys :Space
|
||||||
|
block = <<~BLOCK
|
||||||
|
│ ║ 11
|
||||||
|
│ ║ > 10
|
||||||
|
│ ╚ list ════
|
||||||
|
│ ┏ input ━━━
|
||||||
|
│ ┃ 19/97
|
||||||
|
│ ┃ > 1
|
||||||
|
│ ┗━━━━━━━━━━
|
||||||
|
│ 3
|
||||||
|
│ 2
|
||||||
|
│ 1
|
||||||
|
│
|
||||||
|
╰──────────────
|
||||||
|
BLOCK
|
||||||
|
tmux.until { assert_block(block, _1) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_header_border_and_label
|
||||||
|
tmux.send_keys %(seq 100 | #{FZF} --border rounded --header-lines 3 --header-border sharp --header-label header --header-label-pos 2:bottom --query 1 --padding 1,2), :Enter
|
||||||
|
block = <<~BLOCK
|
||||||
|
│ 12
|
||||||
|
│ 11
|
||||||
|
│ > 10
|
||||||
|
│ ┌────────
|
||||||
|
│ │ 3
|
||||||
|
│ │ 2
|
||||||
|
│ │ 1
|
||||||
|
│ └header──
|
||||||
|
│ 19/97 ─
|
||||||
|
│ > 1
|
||||||
|
│
|
||||||
|
╰────────────
|
||||||
|
BLOCK
|
||||||
|
tmux.until { assert_block(block, _1) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_header_border_and_label_header_first
|
||||||
|
tmux.send_keys %(seq 100 | #{FZF} --border rounded --header-lines 3 --header-border sharp --header-label header --header-label-pos 2:bottom --query 1 --padding 1,2 --header-first), :Enter
|
||||||
|
block = <<~BLOCK
|
||||||
|
│ 12
|
||||||
|
│ 11
|
||||||
|
│ > 10
|
||||||
|
│ 19/97 ─
|
||||||
|
│ > 1
|
||||||
|
│ ┌────────
|
||||||
|
│ │ 3
|
||||||
|
│ │ 2
|
||||||
|
│ │ 1
|
||||||
|
│ └header──
|
||||||
|
│
|
||||||
|
╰────────────
|
||||||
|
BLOCK
|
||||||
|
tmux.until { assert_block(block, _1) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_header_border_and_label_with_list_border
|
||||||
|
tmux.send_keys %(seq 100 | #{FZF} --border rounded --list-border double --list-label list --list-label-pos 2:bottom --header-lines 3 --header-border sharp --header-label header --header-label-pos 2:bottom --query 1 --padding 1,2), :Enter
|
||||||
|
block = <<~BLOCK
|
||||||
|
│ ║ 12
|
||||||
|
│ ║ 11
|
||||||
|
│ ║ > 10
|
||||||
|
│ ╚list════
|
||||||
|
│ ┌────────
|
||||||
|
│ │ 3
|
||||||
|
│ │ 2
|
||||||
|
│ │ 1
|
||||||
|
│ └header──
|
||||||
|
│ 19/97 ─
|
||||||
|
│ > 1
|
||||||
|
│
|
||||||
|
╰────────────
|
||||||
|
BLOCK
|
||||||
|
tmux.until { assert_block(block, _1) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_header_border_and_label_with_list_border_header_first
|
||||||
|
tmux.send_keys %(seq 100 | #{FZF} --border rounded --list-border double --list-label list --list-label-pos 2:bottom --header-lines 3 --header-border sharp --header-label header --header-label-pos 2:bottom --query 1 --padding 1,2 --header-first), :Enter
|
||||||
|
block = <<~BLOCK
|
||||||
|
│ ║ 12
|
||||||
|
│ ║ 11
|
||||||
|
│ ║ > 10
|
||||||
|
│ ╚list════
|
||||||
|
│ 19/97 ─
|
||||||
|
│ > 1
|
||||||
|
│ ┌────────
|
||||||
|
│ │ 3
|
||||||
|
│ │ 2
|
||||||
|
│ │ 1
|
||||||
|
│ └header──
|
||||||
|
│
|
||||||
|
╰────────────
|
||||||
|
BLOCK
|
||||||
|
tmux.until { assert_block(block, _1) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_all_borders
|
||||||
|
tmux.send_keys %(seq 100 | #{FZF} --border rounded --list-border double --list-label list --list-label-pos 2:bottom --header-lines 3 --header-border sharp --header-label header --header-label-pos 2:bottom --query 1 --padding 1,2 --input-border bold --input-label input --input-label-pos 2:bottom), :Enter
|
||||||
|
block = <<~BLOCK
|
||||||
|
│ ║ 12
|
||||||
|
│ ║ 11
|
||||||
|
│ ║ > 10
|
||||||
|
│ ╚list══════
|
||||||
|
│ ┌──────────
|
||||||
|
│ │ 3
|
||||||
|
│ │ 2
|
||||||
|
│ │ 1
|
||||||
|
│ └header────
|
||||||
|
│ ┏━━━━━━━━━━
|
||||||
|
│ ┃ 19/97
|
||||||
|
│ ┃ > 1
|
||||||
|
│ ┗input━━━━━
|
||||||
|
│
|
||||||
|
╰──────────────
|
||||||
|
BLOCK
|
||||||
|
tmux.until { assert_block(block, _1) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_all_borders_header_first
|
||||||
|
tmux.send_keys %(seq 100 | #{FZF} --border rounded --list-border double --list-label list --list-label-pos 2:bottom --header-lines 3 --header-border sharp --header-label header --header-label-pos 2:bottom --query 1 --padding 1,2 --input-border bold --input-label input --input-label-pos 2:bottom --header-first), :Enter
|
||||||
|
block = <<~BLOCK
|
||||||
|
│ ║ 12
|
||||||
|
│ ║ 11
|
||||||
|
│ ║ > 10
|
||||||
|
│ ╚list══════
|
||||||
|
│ ┏━━━━━━━━━━
|
||||||
|
│ ┃ 19/97
|
||||||
|
│ ┃ > 1
|
||||||
|
│ ┗input━━━━━
|
||||||
|
│ ┌──────────
|
||||||
|
│ │ 3
|
||||||
|
│ │ 2
|
||||||
|
│ │ 1
|
||||||
|
│ └header────
|
||||||
|
│
|
||||||
|
╰──────────────
|
||||||
BLOCK
|
BLOCK
|
||||||
tmux.until { assert_block(block, _1) }
|
tmux.until { assert_block(block, _1) }
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user