Skip to content

Commit

Permalink
fix: replace 'vim' hook with generic 'edit' hook (#236)
Browse files Browse the repository at this point in the history
  • Loading branch information
Heiko Nickerl authored Aug 6, 2021
1 parent 798f5b8 commit e24c4dc
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 62 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ Check out the [manpage](/~https://github.com/hnicke/sodalite/blob/master/docs/soda
## FAQ
##### The default 'open' hook doesn't work / launches weird programs :(
Most probably it is not sodalite's fault, but your mime default application list isn't configured correctly.
You could try this:
Run the following command to find the associated application for given file:
```bash
xdg-mime query default $(xdg-mime query filetype <file>)
```
In order to change the default application for a files mime type, run:
```bash
xdg-mime default <desktop> $(xdg-mime query filetype <file>)
```
Expand Down
2 changes: 2 additions & 0 deletions scripts/sodalite-open
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ function set_fallback_editor {
editor=vim
elif type nano; then
editor=nano
elif type vi; then
editor=vi
else
echo "Could not find a suitable editor"; exit 1
fi
Expand Down
6 changes: 3 additions & 3 deletions sodalite/core/action.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import Callable

import sodalite.ui.mmode
from sodalite.core import config, action_def
from sodalite.core.action_def import ActionName
from sodalite.ui import viewmodel
from sodalite.ui.viewmodel import Mode
from sodalite.ui.mmode import Mode


class Action:
Expand All @@ -17,7 +17,7 @@ def __init__(self, name: ActionName, action: Callable[[], None], modes: list[Mod

def handle(self, key: str) -> bool:
if key == self.keybinding:
if self.is_global or viewmodel.global_mode in self.modes:
if self.is_global or sodalite.ui.mmode.global_mode in self.modes:
self.action()
return True
return False
Expand Down
3 changes: 3 additions & 0 deletions sodalite/core/hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from sodalite.core import config
from sodalite.core.config import HooksConfig
from sodalite.ui import notify

if TYPE_CHECKING:
from sodalite.core.entry import Entry
Expand Down Expand Up @@ -36,6 +37,8 @@ def trigger(self, entry: 'Entry') -> None:
logger.info(f"Executing command: {self.action}")
result = os.system(f"( {self.action} ) > /dev/tty < /dev/tty")
logger.info(f"Result is {result}")
if result != 0:
notify.show_error(f"command failed with exit code {result}")
from sodalite.ui import graphics
if self.finally_exit:
graphics.exit(cwd=entry.path)
Expand Down
10 changes: 5 additions & 5 deletions sodalite/core/sodalite.conf
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ hooks:
action: 'sodalite-open "$entry" 2> /dev/null'
label: open
plain_text:
v:
action: 'vim "$entry"'
label: vim
executable:
e:
action: '${EDITOR:-$(which vim || which vi || which nano || echo NO_EDITOR_FOUND)} "$entry"'
label: edit
executable:
r:
action: 'exec "$entry"'
label: execute
label: run
custom:
archive:
extensions: [xz]
Expand Down
29 changes: 15 additions & 14 deletions sodalite/ui/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@
from typing import TYPE_CHECKING

import pyperclip
from urwid import AttrSpec

import sodalite.ui.mmode
from sodalite.core import key as key_module, hook, buffer, operate, Navigator
from sodalite.core.action import Action
from sodalite.core.action_def import ActionName
from sodalite.core.entry import Entry
from sodalite.core.key import Key
from sodalite.ui import graphics, viewmodel, notify, theme
from sodalite.ui import graphics, notify
from sodalite.ui.entrylist import EntryList
from sodalite.ui.viewmodel import Mode, ViewModel
from sodalite.ui.mmode import Mode
from sodalite.ui.viewmodel import ViewModel
from sodalite.util import pubsub

if TYPE_CHECKING:
Expand Down Expand Up @@ -95,9 +96,9 @@ def handle_keypress(self, size: Tuple[int, int], key: str):
if _action.handle(key):
break
except PermissionError:
notify.show((AttrSpec(theme.forbidden + ',bold', '', colors=16), "PERMISSION DENIED"))
notify.show_error("PERMISSION DENIED")
except FileNotFoundError:
notify.show((AttrSpec(theme.forbidden + ',bold', '', colors=16), "FILE NOT FOUND"))
notify.show_error("FILE NOT FOUND")

def handle_key_individually(self, key):
pass
Expand All @@ -117,17 +118,17 @@ def abort(self) -> None:
graphics.exit()

def enter_navigate_mode(self) -> None:
viewmodel.global_mode.mode = Mode.NAVIGATE
sodalite.ui.mmode.global_mode.mode = Mode.NAVIGATE
self.list.render(self.list_size, True)

def enter_assign_mode(self) -> None:
if self.model.current_entry.is_dir:
viewmodel.global_mode.mode = Mode.ASSIGN_CHOOSE_ENTRY
sodalite.ui.mmode.global_mode.mode = Mode.ASSIGN_CHOOSE_ENTRY
self.list.render(self.list_size, True)

def enter_operate_mode(self) -> None:
if self.model.current_entry.is_dir:
viewmodel.global_mode.mode = Mode.OPERATE
sodalite.ui.mmode.global_mode.mode = Mode.OPERATE
self.list.render(self.list_size, True)

def trigger_filter(self) -> None:
Expand Down Expand Up @@ -243,25 +244,25 @@ def __init__(self, frame: 'MainFrame'):
self.actions = actions

def handle_key_individually(self, key):
if viewmodel.global_mode == Mode.ASSIGN_CHOOSE_ENTRY and self.navigator.is_navigation_key(key):
if sodalite.ui.mmode.global_mode == Mode.ASSIGN_CHOOSE_ENTRY and self.navigator.is_navigation_key(key):
self.choose_entry(key)
return True
elif viewmodel.global_mode == Mode.ASSIGN_CHOOSE_KEY and key_module.is_navigation_key(key):
elif sodalite.ui.mmode.global_mode == Mode.ASSIGN_CHOOSE_KEY and key_module.is_navigation_key(key):
self.assign_key(key)
return True

def exit(self) -> None:
if viewmodel.global_mode == Mode.ASSIGN_CHOOSE_ENTRY:
viewmodel.global_mode.mode = Mode.ASSIGN_CHOOSE_KEY
if sodalite.ui.mmode.global_mode == Mode.ASSIGN_CHOOSE_ENTRY:
sodalite.ui.mmode.global_mode.mode = Mode.ASSIGN_CHOOSE_KEY

def choose_entry(self, key: str) -> None:
if key in key_module.get_all_keys():
entry = self.navigator.current_entry.get_child_for_key(Key(key))
assert entry
self.list.select(entry)
viewmodel.global_mode.mode = Mode.ASSIGN_CHOOSE_KEY
sodalite.ui.mmode.global_mode.mode = Mode.ASSIGN_CHOOSE_KEY
elif key == 'enter':
viewmodel.global_mode.mode = Mode.ASSIGN_CHOOSE_KEY
sodalite.ui.mmode.global_mode.mode = Mode.ASSIGN_CHOOSE_KEY

def assign_key(self, key: str):
if key_module.is_navigation_key(key):
Expand Down
3 changes: 2 additions & 1 deletion sodalite/ui/entrylist.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import urwid
from urwid import AttrSpec, ListBox

import sodalite.ui.mmode
from sodalite.core.entry import Entry
from sodalite.core.navigate import Navigator
from sodalite.ui import theme, graphics, viewmodel
Expand Down Expand Up @@ -82,7 +83,7 @@ def render(self, size, focus=False):
caption = " " + key + " "
text = self.entry.name
display = caption + text
if focus and viewmodel.global_mode in viewmodel.ANY_ASSIGN_MODE:
if focus and sodalite.ui.mmode.global_mode in viewmodel.ANY_ASSIGN_MODE:
color = AttrSpec(self.color.foreground + ',standout', self.color.background, colors=16)
else:
color = self.color
Expand Down
3 changes: 2 additions & 1 deletion sodalite/ui/graphics.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
from sodalite.ui.help import HelpLauncher
from sodalite.ui.hookbox import HookBox
from sodalite.ui.mainpane import MainPane
from sodalite.ui.viewmodel import ViewModel, Mode
from sodalite.ui.viewmodel import ViewModel
from sodalite.ui.mmode import Mode
from sodalite.util import env, pubsub

logger = logging.getLogger(__name__)
Expand Down
32 changes: 32 additions & 0 deletions sodalite/ui/mmode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from enum import Enum

from sodalite.util import pubsub


class Mode(Enum):
NAVIGATE = 1
ASSIGN_CHOOSE_ENTRY = 2
ASSIGN_CHOOSE_KEY = 3
OPERATE = 4


class GlobalMode:

def __init__(self):
super().__init__()
self.mode = Mode.NAVIGATE

@property
def mode(self):
return self._mode

@mode.setter
def mode(self, mode: Mode):
self._mode = mode
pubsub.mode_send(self._mode)

def __eq__(self, other):
return self._mode == other or super.__eq__(self, other)


global_mode = GlobalMode()
20 changes: 16 additions & 4 deletions sodalite/ui/notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
import urwid
from urwid import AttrSpec

from sodalite.ui import graphics, theme, viewmodel
from sodalite.ui.viewmodel import Mode
import sodalite.ui.mmode
from sodalite.ui import theme, mmode
from sodalite.ui.mmode import Mode
from sodalite.util import pubsub

txt = urwid.AttrMap(urwid.Text('', align='center'), urwid.DEFAULT)
Expand All @@ -26,9 +27,19 @@ def show(message: Union[str, Tuple[AttrSpec, str]], duration: float = 1.5) -> No
thread.start()


def show_error(message: str, duration: float = 1.5) -> None:
"""
Triggers a notification
:param message: the error to display
:param duration: if set to 0, the message is displayed until another call to 'show' or 'clear'
"""
show((AttrSpec(theme.forbidden + ',bold', '', colors=16), message), duration)


def _show(message: Union[str, Tuple[AttrSpec, str]], duration: float) -> None:
global _last_message
global _original_footer
from sodalite.ui import graphics
frame = graphics.frame
if _notify_lock.locked() and _last_message == message:
return
Expand All @@ -48,15 +59,16 @@ def _show(message: Union[str, Tuple[AttrSpec, str]], duration: float) -> None:


def clear() -> None:
from sodalite.ui import graphics
if graphics.frame and graphics.frame.footer == _notify_box:
graphics.frame.footer = None
graphics.draw_screen()


def trigger_notifications(mode: Mode) -> None:
if viewmodel.global_mode == Mode.ASSIGN_CHOOSE_ENTRY:
if mmode.global_mode == Mode.ASSIGN_CHOOSE_ENTRY:
show("choose entry", duration=0)
elif viewmodel.global_mode == Mode.ASSIGN_CHOOSE_KEY:
elif sodalite.ui.mmode.global_mode == Mode.ASSIGN_CHOOSE_KEY:
show("choose new key", duration=0)
else:
clear()
Expand Down
2 changes: 1 addition & 1 deletion sodalite/ui/theme.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import urwid
from pygments import token

from sodalite.ui.viewmodel import Mode
from sodalite.ui.mmode import Mode
from sodalite.util import pubsub

file = urwid.WHITE
Expand Down
32 changes: 1 addition & 31 deletions sodalite/ui/viewmodel.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,20 @@
import logging
import re
import sre_constants
from enum import Enum
from re import Pattern
from typing import Optional

from sodalite.core.entry import Entry
from sodalite.ui import highlighting
from sodalite.ui.highlighting import HighlightedLine
from sodalite.ui.mmode import Mode
from sodalite.util import pubsub

logger = logging.getLogger(__name__)


class Mode(Enum):
NAVIGATE = 1
ASSIGN_CHOOSE_ENTRY = 2
ASSIGN_CHOOSE_KEY = 3
OPERATE = 4


ANY_ASSIGN_MODE = (Mode.ASSIGN_CHOOSE_KEY, Mode.ASSIGN_CHOOSE_ENTRY)


class GlobalMode:

def __init__(self):
super().__init__()
self.mode = Mode.NAVIGATE

@property
def mode(self):
return self._mode

@mode.setter
def mode(self, mode: Mode):
self._mode = mode
pubsub.mode_send(self._mode)

def __eq__(self, other):
return self._mode == other or super.__eq__(self, other)


global_mode = GlobalMode()


class ViewModel:

def __init__(self) -> None:
Expand Down
2 changes: 1 addition & 1 deletion sodalite/util/pubsub.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

if TYPE_CHECKING:
from sodalite.core.entry import Entry
from sodalite.ui.viewmodel import Mode
from sodalite.ui.mmode import Mode
from sodalite.ui.highlighting import HighlightedLine


Expand Down

0 comments on commit e24c4dc

Please sign in to comment.