Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true

# 4 space indentation
[*.py]
indent_style = space
indent_size = 4
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from setuptools import setup

version = re.search(
'^__version__\s*=\s*"([^"]*)"',
r'^__version__\s*=\s*"([^"]*)"',
open("suplemon/main.py").read(),
re.M
).group(1)
Expand Down
9 changes: 6 additions & 3 deletions suplemon/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,23 @@ def main():
"""Handle CLI invocation"""
# Parse our CLI arguments
config_file = None
log_level = None
if argparse:
parser = argparse.ArgumentParser(description="Console text editor with multi cursor support")
parser.add_argument("filenames", metavar="filename", type=str, nargs="*", help="Files to load into Suplemon")
parser.add_argument("filenames", metavar="filename", type=str, nargs="*", help="files to open")
parser.add_argument("--version", action="version", version=__version__)
parser.add_argument("--config", type=str, help="Configuration file path.")
parser.add_argument("--config", type=str, help="configuration file path")
parser.add_argument("--log-level", type=int, help="debug logging level")
args = parser.parse_args()
filenames = args.filenames
config_file = args.config
log_level = args.log_level
else:
# Python < 2.7 fallback
filenames = sys.argv[1:]

# Generate and start our application
app = App(filenames=filenames, config_file=config_file)
app = App(filenames=filenames, config_file=config_file, log_level=log_level)
if app.init():
app.run()

Expand Down
9 changes: 5 additions & 4 deletions suplemon/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,18 @@ def load_keys(self):
if not os.path.exists(path):
self.logger.debug("Keymap file '{0}' doesn't exist.".format(path))
else:
keymap = self.load_config_file(path) or []
if not keymap:
loaded_keymap = self.load_config_file(path)
if loaded_keymap is False:
self.logger.warning("Failed to load keymap file '{0}'.".format(path))

else:
keymap = loaded_keymap
# Build the key bindings
# User keymap overwrites the defaults in the bindings
self.keymap = self.normalize_keys(self.keymap + keymap)
self.key_bindings = {}
for binding in self.keymap:
for key in binding["keys"]:
self.key_bindings[key] = binding["command"]
self.key_bindings[key] = binding

return True

Expand Down
4 changes: 2 additions & 2 deletions suplemon/config/defaults.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"punctuation": " (){}[]<>$@!%'\"=+-/*.:,;_\n\r",
// Character to use to visualize end of line
"line_end_char": "",
// White space characters and their visual matches
// White space characters and their visual representations
"white_space_map": {
// Null byte as null symbol
"\u0000": "\u2400",
Expand Down Expand Up @@ -100,7 +100,7 @@
"\uFEFF": "\u2420"
},
// Whether to visually show white space chars
"show_white_space": false,
"show_white_space": true,
// Show tab indicators in whitespace
"show_tab_indicators": true,
// Tab indicator charatrer
Expand Down
28 changes: 15 additions & 13 deletions suplemon/config/keymap.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
[
// App
{"keys": ["ctrl+h"], "command": "help"},
{"keys": ["ctrl+s"], "command": "save_file"},
{"keys": ["ctrl+s"], "command": "save"},
{"keys": ["ctrl+e"], "command": "run_command"},
{"keys": ["ctrl+f"], "command": "find"},
{"keys": ["ctrl+g"], "command": "go_to"},
{"keys": ["ctrl+o"], "command": "open"},
{"keys": ["ctrl+w"], "command": "close_file"},
{"keys": ["ctrl+o"], "command": "prompt_open_file"},
{"keys": ["ctrl+w"], "command": "close"},
{"keys": ["ctrl+n"], "command": "new_file"},
{"keys": ["ctrl+q"], "command": "ask_exit"},
{"keys": ["ctrl+q"], "command": "exit"},
{"keys": ["ctrl+p"], "command": "comment"},
{"keys": ["ctrl+pageup"], "command": "next_file"},
{"keys": ["ctrl+pagedown"], "command": "prev_file"},
{"keys": ["shift+pagedown"], "command": "next_view"},
{"keys": ["shift+pageup"], "command": "prev_view"},
{"keys": ["f1"], "command": "save_file_as"},
{"keys": ["f2"], "command": "reload_file"},
{"keys": ["f7"], "command": "toggle_whitespace"},
Expand All @@ -43,12 +43,12 @@
{"keys": ["f9"], "command": "toggle_line_nums"},
{"keys": ["f10"], "command": "toggle_line_ends"},
{"keys": ["f11"], "command": "toggle_highlight"},
{"keys": ["alt+up"], "command": "new_cursor_up"},
{"keys": ["alt+down"], "command": "new_cursor_down"},
{"keys": ["alt+shift+up"], "command": "new_cursor_up"},
{"keys": ["alt+shift+down"], "command": "new_cursor_down"},
{"keys": ["alt+left"], "command": "new_cursor_left"},
{"keys": ["alt+right"], "command": "new_cursor_right"},
{"keys": ["alt+pageup"], "command": "push_up"},
{"keys": ["alt+pagedown"], "command": "push_down"},
{"keys": ["ctrl+shift+up"], "command": "swap_line_up"},
{"keys": ["ctrl+shift+down"], "command": "swap_line_down"},
{"keys": ["ctrl+c"], "command": "copy"},
{"keys": ["ctrl+x"], "command": "cut"},
{"keys": ["ctrl+k"], "command": "duplicate_line"},
Expand All @@ -57,7 +57,9 @@
{"keys": ["ctrl+a"], "command": "find_all"},
{"keys": ["ctrl+left"], "command": "jump_left"},
{"keys": ["ctrl+right"], "command": "jump_right"},
{"keys": ["ctrl+up"], "command": "jump_up"},
{"keys": ["ctrl+down"], "command": "jump_down"},
{"keys": ["alt+up"], "command": "jump_up"},
{"keys": ["alt+down"], "command": "jump_down"},
{"keys": ["ctrl+up"], "command": "scroll_lines", "args": {"amount": 1}},
{"keys": ["ctrl+down"], "command": "scroll_lines", "args": {"amount": -1}},
{"keys": ["ctrl+t"], "command": "strip"}
]
]
62 changes: 31 additions & 31 deletions suplemon/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,31 +60,31 @@ def __init__(self, app, window):
def init(self):
Viewer.init(self)
operations = {
"backspace": self.backspace, # Backspace
"delete": self.delete, # Delete
"insert": self.insert, # Insert
"enter": self.enter, # Enter
"tab": self.tab, # Tab
"untab": self.untab, # Shift + Tab
"escape": self.escape, # Escape
"single_selection": self.single_selection, # Escape
"clear_last_find": self.clear_last_find, # Escape
"new_cursor_up": self.new_cursor_up, # Alt + Up
"new_cursor_down": self.new_cursor_down, # Alt + Down
"new_cursor_left": self.new_cursor_left, # Alt + Left
"new_cursor_right": self.new_cursor_right, # Alt + Right
"page_up": self.page_up, # Page Up
"page_down": self.page_down, # Page Down
"push_up": self.push_up, # Alt + Page Up
"push_down": self.push_down, # Alt + Page Down
"undo": self.undo, # F5
"redo": self.redo, # F6
"toggle_line_nums": self.toggle_line_nums, # F9
"toggle_line_ends": self.toggle_line_ends, # F10
"toggle_highlight": self.toggle_highlight, # F11
"copy": self.copy, # Ctrl + C
"cut": self.cut, # Ctrl + X
"duplicate_line": self.duplicate_line, # Ctrl + W
"backspace": self.backspace,
"delete": self.delete,
"insert": self.insert,
"enter": self.enter,
"tab": self.tab,
"untab": self.untab,
"escape": self.escape,
"single_selection": self.single_selection,
"clear_last_find": self.clear_last_find,
"new_cursor_up": self.new_cursor_up,
"new_cursor_down": self.new_cursor_down,
"new_cursor_left": self.new_cursor_left,
"new_cursor_right": self.new_cursor_right,
"page_up": self.page_up,
"page_down": self.page_down,
"swap_line_up": self.swap_line_up,
"swap_line_down": self.swap_line_down,
"undo": self.undo,
"redo": self.redo,
"toggle_line_nums": self.toggle_line_nums,
"toggle_line_ends": self.toggle_line_ends,
"toggle_highlight": self.toggle_highlight,
"copy": self.copy,
"cut": self.cut,
"duplicate_line": self.duplicate_line,
}
for key in operations.keys():
self.operations[key] = operations[key]
Expand Down Expand Up @@ -411,7 +411,7 @@ def insert_lines_at(self, lines, at):
self.lines.insert(at, Line(line))
self.move_y_cursors(at, len(lines))

def push_up(self):
def swap_line_up(self):
"""Move current lines up by one line."""
used_y = []
curs = sorted(self.cursors, key=lambda c: (c[1], c[0]))
Expand All @@ -426,10 +426,10 @@ def push_up(self):
self.lines[cursor.y] = old
self.move_cursors((0, -1))
self.scroll_up()
# Add a restore point if previous action != push_up
self.store_action_state("push_up")
# Add a restore point if previous action != swap_line_up
self.store_action_state("swap_line_up")

def push_down(self):
def swap_line_down(self):
"""Move current lines down by one line."""
used_y = []
curs = reversed(sorted(self.cursors, key=lambda c: (c[1], c[0])))
Expand All @@ -445,8 +445,8 @@ def push_down(self):

self.move_cursors((0, 1))
self.scroll_down()
# Add a restore point if previous action != push_down
self.store_action_state("push_down")
# Add a restore point if previous action != swap_line_down
self.store_action_state("swap_line_down")

def tab(self):
"""Indent lines."""
Expand Down
6 changes: 3 additions & 3 deletions suplemon/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def save(self):
f = open(self._path(), "w")
f.write(data)
f.close()
except:
except: # noqa: E722 (unrecoverable)
return False
self.data = data
self.last_save = time.time()
Expand Down Expand Up @@ -134,7 +134,7 @@ def _read_text(self, file):
data = f.read()
f.close()
return data
except:
except: # noqa: E722 (unrecoverable)
self.logger.exception("Failed reading file \"{file}\"".format(file=file))
return False

Expand All @@ -152,7 +152,7 @@ def _read_binary(self, file):
return False
self.logger.info("Trying to decode with encoding '{0}'".format(charenc))
return data.decode(charenc)
except:
except: # noqa: E722 (unrecoverable)
self.logger.warning("Failed reading binary file!", exc_info=True)
return False

Expand Down
47 changes: 34 additions & 13 deletions suplemon/key_mappings.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,6 @@
"^Y": "ctrl+y",
"^Z": "ctrl+z", # Conflicts with suspend

544: "ctrl+left",
559: "ctrl+right",
565: "ctrl+up",
524: "ctrl+down",
"kLFT5": "ctrl+left",
"kRIT5": "ctrl+right",
"kUP5": "ctrl+up",
Expand All @@ -124,6 +120,10 @@
"O5R": "ctrl+f3",
"O5S": "ctrl+f4",

"KEY_F(25)": "ctrl+f1",
"KEY_F(26)": "ctrl+f2",
"KEY_F(27)": "ctrl+f3",
"KEY_F(28)": "ctrl+f4",
"KEY_F(29)": "ctrl+f5",
"KEY_F(30)": "ctrl+f6",
"KEY_F(31)": "ctrl+f7",
Expand Down Expand Up @@ -153,6 +153,10 @@
"kPRV3": "alt+pageup",
"kNXT3": "alt+pagedown",

"KEY_F(49)": "alt+f1",
"KEY_F(50)": "alt+f2",
"KEY_F(51)": "alt+f3",
"KEY_F(52)": "alt+f4",
"KEY_F(53)": "alt+f5",
"KEY_F(54)": "alt+f6",
"KEY_F(55)": "alt+f7",
Expand Down Expand Up @@ -185,6 +189,10 @@
"O2R": "shift+f3",
"O2S": "shift+f4",

"KEY_F(13)": "shift+f1",
"KEY_F(14)": "shift+f2",
"KEY_F(15)": "shift+f3",
"KEY_F(16)": "shift+f4",
"KEY_F(17)": "shift+f5",
"KEY_F(18)": "shift+f6",
"KEY_F(19)": "shift+f7",
Expand Down Expand Up @@ -214,15 +222,28 @@
"kEND4": "shift+alt+end",


# Control + Shift
"kUP6": "ctrl+shift+up",
"kDN6": "ctrl+shift+down",
"kLFT6": "ctrl+shift+left",
"kRIT6": "ctrl+shift+right",

"kDC6": "ctrl+shift+delete",
"kHOM6": "ctrl+shift+home",
"kEND6": "ctrl+shift+end",
# Shift + Control
"KEY_F(37)": "shift+ctrl+f1",
"KEY_F(38)": "shift+ctrl+f2",
"KEY_F(39)": "shift+ctrl+f3",
"KEY_F(40)": "shift+ctrl+f4",
"KEY_F(41)": "shift+ctrl+f5",
"KEY_F(42)": "shift+ctrl+f6",
"KEY_F(43)": "shift+ctrl+f7",
"KEY_F(44)": "shift+ctrl+f8",
"KEY_F(45)": "shift+ctrl+f9",
"KEY_F(46)": "shift+ctrl+f10",
"KEY_F(47)": "shift+ctrl+f11",
"KEY_F(48)": "shift+ctrl+f12",

"kUP6": "shift+ctrl+up",
"kDN6": "shift+ctrl+down",
"kLFT6": "shift+ctrl+left",
"kRIT6": "shift+ctrl+right",

"kDC6": "shift+ctrl+delete",
"kHOM6": "shift+ctrl+home",
"kEND6": "shift+ctrl+end",


# Control + Alt
Expand Down
Loading