Skip to content
130 changes: 101 additions & 29 deletions MiniPy.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,107 @@
from math import *
from random import *
from hashlib import md5 as _md5
from hashlib import sha1 as _sha1
from collections import Counter
import datetime
import re
import sublime, sublime_plugin
import sublime
import sublime_plugin


def dnow():
return datetime.datetime.strftime(datetime.datetime.now(), '%d/%m/%Y')


def tnow():
return datetime.datetime.strftime(datetime.datetime.now(), '%H:%M:%S')


def dtnow():
return datetime.datetime.strftime(datetime.datetime.now(), '%d/%m/%Y %H:%M:%S')


def _hashfunc(hashfunc, obj):
s = str(obj)
h = hashfunc(s.encode('utf-8'))
return h.hexdigest()


def md5(obj):
return _hashfunc(_md5, obj)


def sha1(obj):
return _hashfunc(_sha1, obj)


def set_intersect(itr0, itr1):
s0, s1 = set(itr0), set(itr1)
return s0.intersection(s1)


def set_difference(itr0, itr1):
s0, s1 = set(itr0), set(itr1)
return s0 - s1


def set_symdiff(itr0, itr1):
s0, s1 = set(itr0), set(itr1)
return s0.symmetric_difference(s1)


def formatnum(num, digits, scientificNotation=None):

def normalFormatting(num, digits):
return ('{:.%df}' % digits).format(num)

def scientificFormatting(num, digits):
return ('{:.%de}' % digits).format(num)

if scientificNotation is False:
return normalFormatting(num, digits)

if scientificNotation is True:
return scientificFormatting(num, digits)

if scientificNotation is None:
scientificNotation = 8

if isinstance(scientificNotation, int):
if len(normalFormatting(num, digits)) > scientificNotation:
return scientificFormatting(num, digits)
return normalFormatting(num, digits)


# reverse() in python3
def rev(s):
return s[::-1]

# reverse() in python3
def rev(s): return s[::-1]

class Minipy_evalCommand(sublime_plugin.TextCommand):
def run(self, edit, user_input=None):
self.edit = edit
view = self.view
script = ""

# sum the total number of special char $
total = 0
for region in view.sel():
total += view.substr(region).count("$")

print("total = ", total)
# build a list from 1 to the number of special chars
serial_number = list(range(1, total+1))
# serial_number.reverse()
serial_number = rev(serial_number)
print(repr(serial_number))

# replace each special char $ with the next index from serial_number list
# and eval the expression
for region in view.sel():
if region.begin() != region.end():
script = view.substr(region)
for n in range(script.count("$")):
script = re.sub(r"\$", str(serial_number.pop()), script, 1)
# print(eval(script))
view.replace(edit, region, str(eval(script)))
def run(self, edit, user_input=None):
self.edit = edit
view = self.view
script = ""

# sum the total number of special char $
total = 0
for region in view.sel():
total += view.substr(region).count("$")

print("total = ", total)
# build a list from 1 to the number of special chars
serial_number = list(range(1, total + 1))
# serial_number.reverse()
serial_number = rev(serial_number)
print(repr(serial_number))

# replace each special char $ with the next index from serial_number list
# and eval the expression
for region in view.sel():
if region.begin() != region.end():
script = view.substr(region)
for n in range(script.count("$")):
script = re.sub(r"\$", str(serial_number.pop()), script, 1)
# print(eval(script))
view.replace(edit, region, str(eval(script)))
86 changes: 85 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,22 @@

Sublime Text 3 plugin - inline python evaluation.

## Functionality

### As a calculator

For example you can write 3.14*0.6 and get the result (1.884) in your text.
It also supports multiple selection.

### Incremnt counter at cursor positions

Another feature is the use of $ as accumolation variable, e.g. having the following multipe selection:

arr[$]
arr[$]
arr[$]

will result with
will result with

arr[1]
arr[2]
Expand All @@ -23,6 +29,84 @@ similarly:
arr[$+2] -> arr[3]
arr[$*3] arr[6]

### General Python evalueator

Besides that, you have the following imports avaiable:

from math import *
from random import *
from collections import Counter
import datetime
import re # though you should probably use the build in regex features of ST instead.

So you can do:

Counter(('Ann', 'Bob', 'Bob', 'Michael')) -> Counter({'Bob': 2, 'Ann': 1, 'Michael': 1})
Counter(('Ann', 'Bob', 'Bob', 'Michael', 'michael')) -> Counter({'Bob': 2, 'Ann': 1, 'michael': 1, 'Michael': 1})
Counter(name.title() for name in ('Ann', 'Bob', 'Bob', 'Michael', 'michael')) -> Counter({'Bob': 2, 'Michael': 2, 'Ann': 1})

### Computing checksums

And the functions `md5` and `sha1` returns the correspondingly hex-digest of the stringified version of the inputs, e.g. `md5(['foo', 'bar', 'baz']) = dbb432a3f0ac1a2687911715dfbf7502`. Notice that it's possible to hash the list _because it's the string-representation of the list which are being hashed!_

The python `hashlib.md5` and `hashlib.sha1` functions are avaiable under the names `_md5` and `_sha1`.

### Inserting datatimes

The functions `dnow`, `tnow` and `dtnow` return respectively the current string-formatted date, time and datetime:

dnow() -> 03/05/2017
tnow() -> 09:36:03
dtnow() -> 03/05/2017 09:36:03

Notice that you need to have parenthesis after the function name to invoke the function call.


### Computing with sets

While you can just use the regular python to do set computations, there's a few functions included for convinience: `set_intersect`, `set_difference` and `set_symdiff`.

The functions takes two iterable arguments, which are turned into sets, and the computations are performed:

set_intersect('foo bar', 'foo baz') -> {'b', 'a', ' ', 'o', 'f'}
set_intersect('foo baz', 'foo bar') -> {'b', 'a', ' ', 'o', 'f'}
set_difference('foo baz', 'foo bar') -> {'z'}
set_difference('foo bar', 'foo baz') -> {'r'}
set_symdiff('foo baz', 'foo bar') -> {'z', 'r'}
set_symdiff('foo bar', 'foo baz') -> {'z', 'r'}


### Formatting numbers

The fnuction `formatnum` formats numbers, and takes two mandatory and an optional argument:

num
: The number bieng formatted.

digits
: The number of desired digits in the formatted number.

scientificNotation
: Wether of not to use scientific notation.
: Can be True, False or int, where int is the threshold for how many characters the number may contain when formatted un-scientifically, before switching to scientific notation.
: This is the default behaviour, and it's set to 8.

Example usage:

formatnum(0.123456789, 4) -> 0.1235
formatnum(0.123456789, 9) -> 1.234567890e-01
formatnum(123456789.0, 9) -> 1.234567890e+08
formatnum(123456789.0, 2) -> 1.23e+08
formatnum(123.456789, 12) -> 1.234567890000e+02
formatnum(123.456789, 12, False) -> 123.456789000000
formatnum(123.456789, 3) -> 123.457
formatnum(3.14159, 4) -> 3.1416
formatnum(3.14159, 3) -> 3.142
formatnum(3.14159, 2) -> 3.14
formatnum(3.14159, 2, True) -> 3.14e+00
formatnum(3.141592653589793238462643, 3) -> 3.142


## Usage

To evaluate term, highlight and:
Expand Down