colors, ../ och -a
This commit is contained in:
@@ -23,3 +23,8 @@
|
|||||||
- Navigation is limited to the directory containing the applicable `.tui` file.
|
- Navigation is limited to the directory containing the applicable `.tui` file.
|
||||||
- Added `ls --color`-style colors for directories, symlinks, executables, archives and common image files.
|
- Added `ls --color`-style colors for directories, symlinks, executables, archives and common image files.
|
||||||
- Marked paths remain visible as marked when returning to their directory.
|
- Marked paths remain visible as marked when returning to their directory.
|
||||||
|
|
||||||
|
### v2 – cursor and block selection update
|
||||||
|
- Cursor can now move to the empty line immediately below the last object.
|
||||||
|
- `Ctrl+K K` now behaves like joe: the block end is the row immediately above the cursor.
|
||||||
|
- On the bottom empty line, `Ctrl+K K` therefore selects through the last object.
|
||||||
|
|||||||
@@ -227,3 +227,9 @@ tui
|
|||||||
```
|
```
|
||||||
|
|
||||||
The example configuration is in `tui/example.tui`.
|
The example configuration is in `tui/example.tui`.
|
||||||
|
|
||||||
|
### Cursor and block selection
|
||||||
|
|
||||||
|
There is an empty cursor position immediately below the last object in a directory. This makes range selection behave like a text editor.
|
||||||
|
|
||||||
|
`Ctrl+K K` follows joe-style semantics: the end of the selection is the row immediately above the cursor. Thus, when the cursor is on the empty line below the final object, `Ctrl+K K` includes the final object.
|
||||||
|
|||||||
23
tui/tui.py
23
tui/tui.py
@@ -179,7 +179,7 @@ class FileBrowser:
|
|||||||
self.entries = entries
|
self.entries = entries
|
||||||
|
|
||||||
# Cursor 0 is always the synthetic parent entry.
|
# Cursor 0 is always the synthetic parent entry.
|
||||||
self.cursor = min(self.cursor, len(self.entries))
|
self.cursor = min(self.cursor, len(self.entries) + 1)
|
||||||
|
|
||||||
# Marks are global absolute paths, so they survive directory changes.
|
# Marks are global absolute paths, so they survive directory changes.
|
||||||
# Drop marks only for objects that no longer exist.
|
# Drop marks only for objects that no longer exist.
|
||||||
@@ -237,15 +237,20 @@ class FileBrowser:
|
|||||||
if not self.entries:
|
if not self.entries:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.cursor == 0:
|
# Like joe's Ctrl-K K, the end of the block is the line immediately
|
||||||
|
# above the cursor. The bottom empty line therefore selects the last
|
||||||
|
# object in the directory, while standing on an object selects the
|
||||||
|
# object immediately above it.
|
||||||
|
end = self.cursor - 2
|
||||||
|
if end < 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
# K sets/replaces only the end endpoint. The start endpoint is kept.
|
# K sets/replaces only the end endpoint. The start endpoint is kept.
|
||||||
self.selection_end = self.current_entry_index()
|
self.selection_end = end
|
||||||
self._update_selection()
|
self._update_selection()
|
||||||
|
|
||||||
def move(self, delta):
|
def move(self, delta):
|
||||||
self.cursor = max(0, min(len(self.entries), self.cursor + delta))
|
self.cursor = max(0, min(len(self.entries) + 1, self.cursor + delta))
|
||||||
|
|
||||||
def enter(self):
|
def enter(self):
|
||||||
if self.cursor == 0:
|
if self.cursor == 0:
|
||||||
@@ -421,7 +426,7 @@ def draw(stdscr, browser, status=""):
|
|||||||
|
|
||||||
for row in range(visible):
|
for row in range(visible):
|
||||||
index = first + row
|
index = first + row
|
||||||
if index > len(browser.entries):
|
if index > len(browser.entries) + 1:
|
||||||
break
|
break
|
||||||
|
|
||||||
if index == 0:
|
if index == 0:
|
||||||
@@ -429,13 +434,19 @@ def draw(stdscr, browser, status=""):
|
|||||||
text = "../" if entry is not None else "./"
|
text = "../" if entry is not None else "./"
|
||||||
attrs = entry_color(entry) | curses.A_BOLD
|
attrs = entry_color(entry) | curses.A_BOLD
|
||||||
is_marked = False
|
is_marked = False
|
||||||
else:
|
elif index <= len(browser.entries):
|
||||||
entry = browser.entries[index - 1]
|
entry = browser.entries[index - 1]
|
||||||
is_marked = entry.resolve() in browser.marked
|
is_marked = entry.resolve() in browser.marked
|
||||||
attrs = entry_color(entry)
|
attrs = entry_color(entry)
|
||||||
if is_marked:
|
if is_marked:
|
||||||
attrs |= curses.A_REVERSE
|
attrs |= curses.A_REVERSE
|
||||||
text = entry.name + ("/" if entry.is_dir() else "")
|
text = entry.name + ("/" if entry.is_dir() else "")
|
||||||
|
else:
|
||||||
|
# One empty line after the final object, matching the cursor range.
|
||||||
|
entry = None
|
||||||
|
is_marked = False
|
||||||
|
attrs = curses.A_NORMAL
|
||||||
|
text = ""
|
||||||
|
|
||||||
if index == browser.cursor:
|
if index == browser.cursor:
|
||||||
attrs |= curses.A_UNDERLINE
|
attrs |= curses.A_UNDERLINE
|
||||||
|
|||||||
Reference in New Issue
Block a user