Как стать автором
Обновить

Комментарии 16

А vim вроде и так это умеет…
Именно так не умеет, но решается одной строкой в конфиге.
Insert mode:
Ctrl+r
=
100500 + 1
<enter>
А задача немного другая…
— выделяем арифметическое выражение
— нажимаем что-то
— на месте выделенного выражения видим результат вычисления
Один раз выполняем
:vnoremap t c <C-r>= <C-r>" <cr>


— выделяем арифметическое выражение
— нажимаем t
— на месте выделенного выражения видим результат вычисления
Emacs тоже. Правда писать придется в префиксной нотации :)
В форму добавления комментария на хабре при этом вставляет тескт скрипта =) Но в Sublime работает и это главное! Спасибо!

Перевесил на другой хоткей — все вставляется нормально 5+5=10.
Плагин для Sublime Text:

import sublime, sublime_plugin

class EvalCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		for region in self.view.sel():
			if not region.empty():
				s = self.view.substr(region)
				self.view.replace(edit, region, str(eval(s)))
Да, чтобы повесить хоткей, идём в Preferences -> Key Bindings — User и добавляем

[ ... ,{ "keys": ["ctrl+shift+c"], "command": "eval", "args": {} } ]
eval? Серьезно?

Если я дурак выделю строку

import os;os.system(«rm -rf ~»);

А затем нажму ctrl+shift+c?

Ну если вы так просите

import sublime_plugin
import ast, operator as op

# supported operators
operators = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul, 
             ast.Div: op.truediv, ast.Pow: op.pow, ast.BitXor: op.xor}

def eval_expr(expr):
	return eval_(ast.parse(expr).body[0].value)

def eval_(node):
    if isinstance(node, ast.Num):
        return node.n
    if isinstance(node, ast.operator):
        return operators[type(node)]
    if isinstance(node, ast.BinOp):
        return eval_(node.op)(eval_(node.left), eval_(node.right))
    raise TypeError(node)

class EvalCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		for r, s in [(r, self.view.substr(r)) for r in self.view.sel() if not r.empty()]:
			self.view.replace(edit, r, str(eval_expr(s)))
Хотя я бы предпочёл не терять мощь питона и делать хотя бы что-то вроде "Hello!" * 50. Поэтому вот вариант получше:

import sublime_plugin

ns = {}
ns.update(vars(__import__('math')).copy())
ns['__builtins__'] = None

class EvalCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		for r, s in [(r, self.view.substr(r)) for r in self.view.sel() if not r.empty()]:
			self.view.replace(edit, r, str(eval(s, ns)))

Делаем доступными функции из модуля math. Вариант тоже немного греховный (подробнее), но совсем немного :-)
$BOOFER — это круто
Спасибо, исправил. В начале заметки я написал, что воспользовался частями кода из статьи imitsuran, не внося коррективы в названия переменных (да чего уже греха таить — внимания не обратил), отсюда и BOOFER.
Вот вам вычисление арифметических выражений в текстовом редакторе:

_12546|82
 82   |----
 _434 |153
  410
  _246
   246
     0
Сделал аналогично средствами текстового редактора Geany, в котором работаю, правда использовал wcalc (от bc отказался по разным причинам). Хотя конечно гораздо лучше, чтобы работало везде.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории