Git Product home page Git Product logo

suplemon's Introduction

Suplemon ๐Ÿ‹

Build Status Join the chat at https://webchat.freenode.net/?channels=%23suplemon Run on Repl.it

      ___________   _________  ___     ______________________________   ___
     /  _____/  /  /  /  _   \/  /\   /  ______/        /  ___   /   | /  /\
    /  /____/  /  /  /  /_/  /  / /  /  /_____/  /  /  /  /  /  /    |/  / /
   /____   /  /  /  /  _____/  / /  /  ______/  /  /  /  /  /  /  /|    / /
  _____/  /  /__/  /  /\___/  /____/  /_____/  /  /  /  /__/  /  / |   / /
 /_______/\_______/__/ /  /_______/________/__/__/__/________/__/ /|__/ /
 \_______\ \______\__\/   \_______\________\__\__\__\________\__\/ \__\/

          Remedying the pain of command line editing since 2014

Suplemon is a modern, powerful and intuitive console text editor with multi cursor support. Suplemon replicates Sublime Text style functionality in the terminal with the ease of use of Nano. http://github.com/richrd/suplemon

Suplemon in action

Features

  • Proper multi cursor editing, as in Sublime Text
  • Syntax highlighting with Text Mate themes
  • Autocomplete (based on words in the files that are open)
  • Easy Undo/Redo (Ctrl + Z, Ctrl + Y)
  • Copy & Paste, with multi line support (and native clipboard support on X11 / Unix and Mac OS)
  • Multiple files in tabs
  • Powerful Go To feature for jumping to files and lines
  • Find, Find next and Find all (Ctrl + F, Ctrl + D, Ctrl + A)
  • Custom keyboard shortcuts (and easy-to-use defaults)
  • Mouse support
  • Restores cursor and scroll positions when reopenning files
  • Extensions (easy to write your own)
  • Lots more...

Caveats

  • Currently no built in selections (regions). To copy part of a line select it with your mouse and use Ctrl + Shift + C

Try it!

You can just clone the repo, and try Suplemon, or also install it system wide. To run from source you need to install the python wcwidth package.

pip3 install wcwidth
git clone https://github.com/richrd/suplemon.git
cd suplemon
python3 suplemon.py

Installation

Install the latest version from PIP:

sudo pip3 install suplemon

To install Suplemon from the repo run the setup script:

sudo python3 setup.py install

Usage

suplemon # New file in the current directory
suplemon [filename]... # Open one or more files
suplemon [filename:row:col]... # Open one or more files at a specific row or column (optional)

Notes

  • Must use Python 3.3 or higher for proper character encoding support.
  • Python2.7 (and maybe lower) versions work, but aren't officially supported (some special characters won't work etc).
  • The master branch is considered stable.
  • Tested on Unix.

Dev Branch Status: Build Status

No dependencies outside the Python Standard Library required.

Optional dependencies

  • Pygments

For support for syntax highlighting over 300 languages.

  • Flake8

For showing linting for Python files.

  • xsel or xclip

For system clipboard support on X Window (Linux).

  • pbcopy / pbpaste

For system clipboard support on Mac OS.

See docs/optional-dependencies.md for installation instructions.

Description

Suplemon is an intuitive command line text editor. It supports multiple cursors out of the box. It is as easy as nano, and has much of the power of Sublime Text. It also supports extensions to allow all kinds of customizations. To get more help hit Ctrl + H in the editor. Suplemon is licensed under the MIT license.

Configuration

Main Config

The suplemon config file is stored at ~/.config/suplemon/suplemon-config.json.

The best way to edit it is to run the config command (Run commands via Ctrl+E). That way Suplemon will automatically reload the configuration when you save the file. To view the default configuration and see what options are available run config defaults via Ctrl+E.

Keymap Config

Below are the default key mappings used in suplemon. They can be edited by running the keymap command. To view the default keymap file run keymap default

  • Ctrl + Q

    Exit

  • Ctrl + W

    Close file or tab

  • Ctrl + C

    Copy line(s) to buffer

  • Ctrl + X

    Cut line(s) to buffer

  • Ctrl + V

    Insert buffer

  • Ctrl + K

    Duplicate line

  • Ctrl + G

    Go to line number or file (type the beginning of a filename to switch to it). You can also use 'filena:42' to go to line 42 in filename.py etc.

  • Ctrl + F

    Search for a string or regular expression (configurable)

  • Ctrl + D

    Search for next occurrence or find the word the cursor is on. Adds a new cursor at each new occurrence.

  • Ctrl + T

    Trim whitespace

  • Alt + Arrow Key

    Add new cursor in arrow direction

  • Ctrl + Left / Right

    Jump to previous or next word or line

  • ESC

    Revert to a single cursor / Cancel input prompt

  • Alt + Page Up

    Move line(s) up

  • Alt + Page Down

    Move line(s) down

  • Ctrl + S

    Save current file

  • F1

    Save file with new name

  • F2

    Reload current file

  • Ctrl + O

    Open file

  • Ctrl + W

    Close file

  • Ctrl + Page Up

    Switch to next file

  • Ctrl + Page Down

    Switch to previous file

  • Ctrl + E

    Run a command.

  • Ctrl + Z and F5

    Undo

  • Ctrl + Y and F6

    Redo

  • F7

    Toggle visible whitespace

  • F8

    Toggle mouse mode

  • F9

    Toggle line numbers

  • F11

    Toggle full screen

Mouse shortcuts

  • Left Click

    Set cursor at mouse position. Reverts to a single cursor.

  • Right Click

    Add a cursor at mouse position.

  • Scroll Wheel Up / Down

    Scroll up & down.

Commands

Suplemon has various add-ons that implement extra features. The commands can be run with Ctrl + E and the prompt has autocomplete to make running them faster. The available commands and their descriptions are:

  • autocomplete

    A simple autocompletion module.

    This adds autocomplete support for the tab key. It uses a word list scanned from all open files for completions. By default it suggests the shortest possible match. If there are no matches, the tab action is run normally.

  • autodocstring

    Simple module for adding docstring placeholders.

    This module is intended to generate docstrings for Python functions. It adds placeholders for descriptions, arguments and return data. Function arguments are crudely parsed from the function definition and return statements are scanned from the function body.

  • bulk_delete

    Bulk delete lines and characters. Asks what direction to delete in by default.

    Add 'up' to delete lines above highest cursor. Add 'down' to delete lines below lowest cursor. Add 'left' to delete characters to the left of all cursors. Add 'right' to delete characters to the right of all cursors.

  • comment

    Toggle line commenting based on current file syntax.

  • config

    Shortcut for openning the config files.

  • crypt

    Encrypt or decrypt the current buffer. Lets you provide a passphrase and optional salt for encryption. Uses AES for encryption and scrypt for key generation.

  • diff

    View a diff of the current file compared to it's on disk version.

  • eval

    Evaluate a python expression and show the result in the status bar.

    If no expression is provided the current line(s) are evaluated and replaced with the evaluation result.

  • keymap

    Shortcut to openning the keymap config file.

  • linter

    Linter for suplemon.

  • lower

    Transform current lines to lower case.

  • lstrip

    Trim whitespace from beginning of current lines.

  • paste

    Toggle paste mode (helpful when pasting over SSH if auto indent is enabled)

  • reload

    Reload all add-on modules.

  • replace_all

    Replace all occurrences in all files of given text with given replacement.

  • reverse

    Reverse text on current line(s).

  • rstrip

    Trim whitespace from the end of lines.

  • save

    Save the current file.

  • save_all

    Save all currently open files. Asks for confirmation.

  • sort_lines

    Sort current lines.

    Sorts alphabetically by default. Add 'length' to sort by length. Add 'reverse' to reverse the sorting.

  • strip

    Trim whitespace from start and end of lines.

  • tabstospaces

    Convert tab characters to spaces in the entire file.

  • toggle_whitespace

    Toggle visually showing whitespace.

  • upper

    Transform current lines to upper case.

Support

If you experience problems, please submit a new issue. If you have a question, need help, or just want to chat head over to the IRC channel #suplemon @ Freenode. I'll be happy to chat with you, see you there!

Development

If you are interested in contributing to Suplemon, development dependencies can be installed via:

# For OS cleanliness, we recommend using `virtualenv` to prevent global contamination
pip install -r requirements-dev.txt

After those are installed, tests can be run via:

./test.sh

PRs are very welcome and appreciated. When making PRs make sure to set the target branch to dev. I only push to master when releasing new versions.

Rationale

For many the command line is a different environment for text editing. Most coders are familiar with GUI text editors and for many vi and emacs have a too steep learning curve. For them (like for me) nano was the weapon of choice. But nano feels clunky and it has its limitations. That's why I wrote my own editor with built in multi cursor support to fix the situation. Another reason is that developing Suplemon is simply fun to do.

suplemon's People

Contributors

abl avatar caph1993 avatar consolatis avatar gnewbee avatar lchris314 avatar mosrod avatar richrd avatar severin31 avatar trylle avatar twolfson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

suplemon's Issues

Retain cursor x coordinate when moving vertically.

When moving to a line shorter than the x coordinate of the cursor the x coordinate is reverted to the length of the line.
Instead suplemon should remember the x coordinate and use it when the line is long enough.

_curses.error

Trying to run suplemon causes an instant crash on Python 3.2.3:

python3 main.py main.py

Traceback (most recent call last):                                           
  File "main.py", line 490, in <module>                                      
    ui.wrapper(main)                                                         
  File "/home/pi/suplemon/ui.py", line 20, in wrapper                        
    curses.wrapper(func)                                                     
  File "/usr/lib/python3.2/curses/wrapper.py", line 43, in wrapper           
    return func(stdscr, *args, **kwds)                                       
  File "main.py", line 486, in main                                          
    app.run()                                                                
  File "main.py", line 97, in run                                            
    self.load()                                                              
  File "main.py", line 86, in load                                           
    self.ui.load()                                                           
  File "/home/pi/suplemon/ui.py", line 90, in load                           
    curses.curs_set(0)                                                       
_curses.error: curs_set() returned ERR

no colors in TTY

suplemon renders colors perfectly in a graphical terminal, yet it does not issue colors in a standard TTY on my machine. It may have to be double checked as my machine could be unusual.

`ctrl+k` doesn't respect `n`/`N` when asking to close file

I stumbled across the ctrl+k command when attempting to delete a line as in Sublime Text (i.e. ctrl+k,ctrl+k). This seems to be bound to a "Close File" command but it isn't respecting when I say "N":

Opened new file:

selection_131

Pressed ctrl+k:

selection_132

Typed N and pressed enter:

selection_133

Expected behavior: File does not close

Actual behavior: Buffer resets or file closes (not sure which)

OS information: Running on [email protected](1) on Linux Mint 17.1 64 bit

Mac: Backspace key doesn't work

Great editor! One small issue - on my Mac the Backspace key produces ^?. Is there a config file where I can change that behavior?

Thanks
Mike

Add support for Homebrew

One of the easiest ways to get this in the hands of a lot of users is creating a Homebrew formula - well, once OS X support is working 100% :)

I'm erring on the side of being overly detailed here - apologies if I'm covering familiar ground!

  1. Homebrew relies on semver; I notice you went from "0.1.11" to "0.1.2" which, in semver, would be a step backwards. (0.1.2 < 0.1.11 < 0.1.12 < 0.1.20)
  2. Homebrew requires a stable release - it's possible to also have a HEAD and Devel channel, but packages that only have HEAD/Devel are not available by default to users. The easiest way to accomplish this is by tagging releases - if you tag a release as 0.1.3 GitHub will automatically create a tarball.
  3. Some kind of launcher script is necessary - it's possible to embed that in to the Homebrew formula, but it's frowned upon.

A formula for Suplemon would probably look like the following - copied and pasted from the Homebrew formula template.

class Suplemon < Formula
  desc "Console text editor with multi cursor support. Suplemon replicates Sublime Text style functionality in the terminal."
  homepage "https://github.com/richrd/suplemon"
  version "0.1.3"
  url "https://github.com/richrd/suplemon/archive/0.1.3.tar.gz"
  head "https://github.com/richrd/suplemon.git"

  devel do
    url "https://github.com/richrd/suplemon.git", :using => :git, :branch => "dev"
    version "dev"
  end

  depends_on 'python3'
  depends_on 'coreutils' # greadlink for greadlink -f

  def install
    libexec.install Dir["*.py"]
    libexec.install Dir["modules"]
    libexec.install Dir["linelight"]
    bin.install "supl"
  end

end

Homebrew works by creating a series of symlinked repositories of various versions, etc - anything not specified during the install step is removed. (The formula spec makes a lot more sense when your last step is make install.) Here, I'm dumping everything in to libexec except for the supl launcher command; anything put in bin ends up on the user's path.

With this formula, a user could...

  1. brew install suplemon to get 0.1.3
  2. brew install suplemon --HEAD to get whatever is at the tip of master.
  3. brew install suplemon --devel to get whatever is at the tip of dev. (--devel is supposed to be for alpha/canary versions; --HEAD is supposed to be for the literal bleeding edge - it might make sense to not support --devel and have --HEAD point to the dev branch.)

The supl command would probably look like...

#!/bin/sh
TARGET=`greadlink -f $0`
`dirname $TARGET`/../libexec/cli.py $*

The real thing should probably be a bit more intelligent (and useful for non-Homebrew users, of course. :)

Screen flickers on some terminals and slow connections.

Suplemon "redraws" the entire screen on each update, even if only one character or line has changed. This means that any change sends the entire view to the terminal. This causes flickering and sometimes slows down the app on a slow connection. Should optimize rendering to only redraw lines that changed.

No response on Ubuntu

I cloned the project and typed python3.4 main.py in Terminal. The ui has loaded, but it had no response when I typed anything. The cursor could not blink and move.

When I typed Ctrl + C to kill it. It printed:

Traceback (most recent call last):
  File "/home/devis/suplemon/main.py", line 443, in <module>
    ui.wrapper(main)
  File "/home/devis/suplemon/ui.py", line 22, in wrapper
    curses.wrapper(func)
  File "/usr/local/lib/python3.4/curses/__init__.py", line 94, in wrapper
    return func(stdscr, *args, **kwds)
  File "/home/devis/suplemon/main.py", line 436, in main
    app.run()
  File "/home/devis/suplemon/main.py", line 70, in run
    self.main_loop()
  File "/home/devis/suplemon/main.py", line 78, in main_loop
    self.ui.update()
  File "/home/devis/suplemon/ui.py", line 164, in update
    self.check_resize()
KeyboardInterrupt

but sometimes it printed:

Traceback (most recent call last):
  File "/home/devis/suplemon/main.py", line 443, in <module>
    ui.wrapper(main)
  File "/home/devis/suplemon/ui.py", line 22, in wrapper
    curses.wrapper(func)
  File "/usr/local/lib/python3.4/curses/__init__.py", line 94, in wrapper
    return func(stdscr, *args, **kwds)
  File "/home/devis/suplemon/main.py", line 436, in main
    app.run()
  File "/home/devis/suplemon/main.py", line 70, in run
    self.main_loop()
  File "/home/devis/suplemon/main.py", line 80, in main_loop
    event = self.ui.get_input()
KeyboardInterrupt

It is so strange.

Cut command works incorrectly with multiple cursors.

Cutting with cursors on multiple lines fails. Instead only lines at the first cursor are cut.
Example:
Cutting lines 1 and 4 actually cuts 1 and 2.

|1 line one
2 line two
3 line three
|4 line four

Result:

|3 line three
|4 line four

Expected:

|2 line two
3 line three
| 

OS X input handling in prompts doesn't support backspace

I'll try to dig deeper but figured I'd post this in case it's obvious.

Normal editing works great; prompts (e.g. Save As / Exit Without Saving) do not support backspace.

Python version 3.4.3; built with Homebrew; 5913e4e

To reproduce, just open a file, press F1 to Save As, and attempt to backspace; nothing happens - not even a bell.

Reproduced on iTerm2 and on Apple Terminal.

suplemon launcher (supl?) script

I'm trying to replace my use of nano and ST3 with suplemon; one thing that would be really helpful (and I'm currently hacking around with aliases) would be a launcher script in the style of "subl" for Sublime Text.

Currently, if I symlink cli.py to /usr/local/bin/supl it, of course, fails; this has the side effect of making it hard to write a Homebrew formula (which might get a lot of extra users of suplemon. :)

Something as simple as:

#!/bin/sh
TARGET=`readlink $0`
`dirname $TARGET`/cli.py $*

might work. Note that normally readlink -f $0 would be ideal but the -f flag isn't supported on OS X. http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac goes in to a lot of detail.

Unsolicited critique

I have been digging around the source code a little bit and seeing some room for improvement. The general direction of the project is good but I think things might be smoother with a nudge in the right direction.

Larger items

Language choice

The project's goal is to be a CLI clone of Sublime Text and everyone talks to Sublime Text via it's Python plugin system. Great choice with regard to Python ๐Ÿ‘

File architecture

It's usually not the best idea to keep most files in the root project folder. At some point, there become too many files and you feel like you are drowning. In Python projects, people usually relocate them into a folder with the project's name:

  • suplemon/ - Git repo folder
    • suplemon/ - Container for all code related project files
      • main.py - Starting point for our application
      • linelight/ - Syntax highlighting files
      • ...

CLI invocation

The current method of starting suplemon is great for a proof of concept but doesn't allow for a lot of flexibility with CLI arguments (e.g. handling --version).

suplemon/main.py

Lines 446 to 458 in 915c0c0

def load_files(self):
"""Try to load all files specified in arguments."""
#TODO: Maybe use argparse for this
if len(sys.argv) > 1:
names = sys.argv[1:]
for name in names:
if self.file_is_open(name): continue
if self.open_file(name):
loaded = True
else:
self.new_file(name)
else:
self.load_default()

suplemon/main.py

Lines 488 to 493 in 915c0c0

if __name__ == "__main__":
"""Only run the app if it's run directly (not imported)."""
ui.wrapper(main)
# Output log info
if app.config["app"]["debug"]:
app.logger.output()

I suggest creating a bin/ folder and a suplemon.py script there. From this point, there are 2 approaches I have seen:

  • Use argparse and perform all logic for interpretting arguments/setting up a config here
import argparse

parser = argparse.ArgumentParser(...)
  • Create a suplemon/cli.py next to main.py which exposes a function cli() to parse arguments
# Inside `cli.py`
import argparse

def cli():
    parser = argparse.ArgumentParser(...)

# Inside `bin/suplemon.py`
from cli import cli
cli()

In both cases, we:

  1. Interpret CLI arguments and initialize App() with our customized configuration (i.e. App(config))
  2. If there were any files requested, invoke appropriate commands on App() to load them up

Pythonic anti-patterns

Using import * is a very big bad Pythonic anti-pattern. It makes it harder to find out where a function comes from which slows down new contributors. Please consider removing those =/

Linting/tests

There is no linting/tests. For new contributors, a lack of tests is a deterent because there is no way to verify they haven't broken anything.

As for linting, it saves a ton of time on PRs for people missing docstrings/using incorrect quotes. Additionally, it makes the project feel consistent which means code can be shifted around more easily. I recommend using flake8 and flake8-quotes; it's not overwhelming with its linting and has a nice extension system.

https://pypi.python.org/pypi/flake8

https://github.com/zheller/flake8-quotes

Command consistency with Sublime Text

A good amount of commands are consistent with Sublime Text. This is great because it makes the APIs/plugins easier to reuse between the systems. However, there are a few that are straying (e.g. prev_file vs prev_view):

https://github.com/randy3k/sublime-default/blob/5c296d63820968a1fe1e0c9a54cb0a2cd7c65595/Default%20%28Linux%29.sublime-keymap#L90-L91

suplemon/main.py

Lines 48 to 49 in 915c0c0

"prev_file": self.prev_file,
"next_file": self.next_file,

Additionally, for things like scrolling we can input custom arguments to the commands (actually keyword arguments/kwargs):

https://github.com/randy3k/sublime-default/blob/5c296d63820968a1fe1e0c9a54cb0a2cd7c65595/Default%20%28Linux%29.sublime-keymap#L87-L88

Shortcut consistency with Sublime Text

We already discussed this in #49 but to reiterate, it would be nice to be as close to Sublime Text to make switching contexts easier.

https://github.com/randy3k/sublime-default/blob/5c296d63820968a1fe1e0c9a54cb0a2cd7c65595/Default (Linux).sublime-keymap

Breakdown App

main.py has grown quite large. We should consider breaking out the sections into classes that mixin or are modules themselves.

https://github.com/richrd/suplemon/blob/915c0c0485dcae795c577f2e57329c5031d5c8d1/main.py

Use Python logging library

While generating a custom logger works, it isn't as practical/error proof as Python's built in logger. We should consider using the logging module instead.

https://github.com/richrd/suplemon/blob/915c0c0485dcae795c577f2e57329c5031d5c8d1/logger.py

https://docs.python.org/3.4/library/logging.html

Configuration management

Use a ~/.config/suplemon/ folder for multiple files over a single file at ~/.suplemon-config.json. There are a few reasons for this:

  • Not compatible with Sublime Text
  • Combined files become larger which makes it harder to search through as a user
  • People hate more files in their ~ folder (hence ~/.config)

As for where we keep the defaults, I suggest removing them from config and storing them as .json files along side in a suplemon/config/ folder. This will keep the paradigms consistent between ~/.config/ and suplemon itself.

suplemon/config.py

Lines 17 to 45 in 915c0c0

self.defaults = {
"app": {
# Print debug logging
"debug": 1,
# How long curses will wait to detect ESC key
"escdelay": 50,
# Wether to use special unicode symbols for decoration
"use_unicode_symbols": 0,
# Key bindings for app functions
"keys": {
"^H": "help", # Ctrl + H
"^S": "save_file", # Ctrl + S
"^E": "run_command", # Ctrl + E
"^F": "find", # Ctrl + F
"^G": "go_to", # Ctrl + G
"^O": "open", # Ctrl + O
"^K": "close_file", # Ctrl + K
"^N": "new_file", # Ctrl + N
"^X": "ask_exit", # Ctrl + X
554: "next_file", # Ctrl + Page Up
549: "prev_file", # Ctrl + Page Down
"kNXT5": "next_file", # Ctrl + Page Up
"kPRV5": "prev_file", # Ctrl + Page Down
265: "save_file_as", # F1
266: "reload_file", # F2
272: "toggle_mouse", # F8
275: "toggle_fullscreen", # F12
}
},

Small items

app.log method

Both redefining logger methods on app and passing in log_type as a parameter are unnecessary conventions. Python's logging library has multiple methods for each different level (e.g. logger.info, logger.debug). We should move the logging and pick up those methods for free. Additionally, redefining the methods on app is impractical and leads to redundant code:

app.logger.info("Hello World!")

Always use interpolation or .format

Python has built in suport for making concatenated strings presentable via interpolation. We should stop using concatenation and move to interpolation as it's more Pythonic:

self.logger.log("Looking for command '{cmd}'".format(cmd=cmd), LOG_INFO)

suplemon/main.py

Lines 296 to 298 in 915c0c0

self.logger.log("Looking for command '" + cmd +"'", LOG_INFO)
if cmd in self.modules.modules.keys():
self.logger.log("Trying to run command '" + cmd +"'", LOG_INFO)

Coding consistency

You are always using always using double quotes for strings. That is great to see as it leads to the project feeling more consistent as a whole ๐Ÿ‘

Most functions have docstrings which is great. One note on this, you might want to consider using Sphinx notation for documenting parameters/return values as well:

http://sphinx-doc.org/domains.html#info-field-lists

Inconsistent spacing sometimes

You are pretty good with your spacing being consistent (e.g. spaces before/after +, ==). However, there were a few spots that didn't have consistency. Typically a linter will catch this.

self.logger.log("Looking for command '" + cmd +"'", LOG_INFO)

self.logger.log("Looking for command '" + cmd +"'", LOG_INFO)
# should be
self.logger.log("Looking for command '" + cmd + "'", LOG_INFO)

self.log("Loading: "+str(item), LOG_INFO)

self.log("Loading: "+str(item), LOG_INFO)
# should be
self.log("Loading: " + str(item), LOG_INFO)

path = os.path.join(self.module_path, name+".py")

self.log("Failed loading module:"+str(name))

Use key bindings from app for legend

The show_legend command isn't using the key bindings from app/config. This could lead to inconsistencies later on.

suplemon/ui.py

Lines 308 to 324 in 915c0c0

("^S", "Save"),
("F1", "Save as"),
("F2", "Reload"),
("F5", "Undo"),
("F6", "Redo"),
("^O", "Open"),
("^C", "Cut"),
("^V", "Paste"),
("^F", "Find"),
("^D", "Find next"),
("^A", "Find all"),
("^W", "Duplicate line"),
("ESC", "Single cursor"),
("^G", "Go to"),
("^E", "Run command"),
("F8", "Mouse mode"),
("^X", "Exit"),

Syntax highlighting

Our current syntax highlighter is pretty naive (e.g. doesn't handle lines with multiple commands well). We should consider using a more fully fledged one like pygments with a custom formatter:

https://github.com/richrd/suplemon/blob/915c0c0485dcae795c577f2e57329c5031d5c8d1/linelight/js.py

http://pygments.org/docs/formatters/

Key bindings

Our current key bindings like kNXT5 are cryptic. We should aim for a setup closer to Sublime Text (e.g. ctrl+pageup)

"kNXT5": "next_file", # Ctrl + Page Up

https://github.com/randy3k/sublime-default/blob/5c296d63820968a1fe1e0c9a54cb0a2cd7c65595/Default%20%28Linux%29.sublime-keymap#L91

Add more key bindings for python2.

Incomplete list of additional bindings:

App

kNXT5: prev_file
kPRV5: next_file

Editor

^I: tab
kDN3: new_cursor_down
kUP3: new_cursor_up
kRIT5: jump_right
kLFT5: jump_left

Suggestion for refactoring

Hi, nice work on the editor! You should consider this when refactoring the code- currently in line 606, file editor.py there is a huge conditional with lots of branches for comparing the keys. What I suggest is that you instead use a dictionary to hold all the callbacks, i.e.

class Editor(Viewer):
    key_mappings = {}
    #...

Editor.key_mappings.update({
    curses.KEY_RIGHT: dispatch('arrow_right')
})

Where dispatch is a function that returns a closure that when called with an instance, it dispatches to the enclosed attribute. Then the code in handle_input would be easier to implement as well:

def handle_input(self, event):
    if event.type == "mouse":
        return False
    key = event.key_code
    if key in self.key_mappings:
        self.key_mappings[key]()
        return
    try:
        self.type(key)
    except:
        pass

Pragmatic considerations aside, this also trades space for time, as the conditional runs in O(n), where n is relative to the key. This implementation runs in O(1), and also allows plugins to map keys to their own callbacks, a la Vim. Also it reflects the mental model of the editor being a program that just responds to events and acts on the text. You can also use a list to store the callbacks to be invoked when keys are pressed, but that's another story.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.