diff --git a/cli/js/ts_global.d.ts b/cli/js/ts_global.d.ts
index 7b9d84c7ad..bca602998d 100644
--- a/cli/js/ts_global.d.ts
+++ b/cli/js/ts_global.d.ts
@@ -9,6 +9,8 @@
 // deno_typescript/typescript/lib/typescript.d.ts. Ideally we could simply point
 // to that in this import specifier, but "cargo package" is very strict and
 // requires all files to be present in a crate's subtree.
+// to get proper editor intellisense, you can substitute "$asset$" with
+// "../../deno_typescript/typescript/lib" - remember to revert before committing
 // eslint-disable-next-line @typescript-eslint/no-unused-vars
 import * as ts_ from "$asset$/typescript.d.ts";
 
diff --git a/tools/format.py b/tools/format.py
index 037d56bacd..ffeaa250db 100755
--- a/tools/format.py
+++ b/tools/format.py
@@ -4,17 +4,37 @@ import os
 import sys
 import argparse
 from third_party import python_env
-from util import git_ls_files, third_party_path, root_path, run
+from util import git_ls_files, git_staged, third_party_path, root_path
+from util import print_command, run
+
+cmd_args = None
 
 
-def main():
-    os.chdir(root_path)
+def get_cmd_args():
+    global cmd_args
+
+    if cmd_args:
+        return cmd_args
 
     parser = argparse.ArgumentParser()
     parser.add_argument("--js", help="run prettier", action="store_true")
     parser.add_argument("--py", help="run yapf", action="store_true")
     parser.add_argument("--rs", help="run rustfmt", action="store_true")
-    args = parser.parse_args()
+    parser.add_argument(
+        "--staged", help="run only on staged files", action="store_true")
+    cmd_args = parser.parse_args()
+    return cmd_args
+
+
+def get_sources(*args):
+    getter = git_staged if get_cmd_args().staged else git_ls_files
+    return getter(*args)
+
+
+def main():
+    os.chdir(root_path)
+
+    args = get_cmd_args()
 
     did_fmt = False
     if args.js:
@@ -34,36 +54,41 @@ def main():
 
 
 def prettier():
-    print "prettier"
     script = os.path.join(third_party_path, "node_modules", "prettier",
                           "bin-prettier.js")
-    source_files = git_ls_files(root_path, ["*.js", "*.json", "*.ts", "*.md"])
-    run(["node", script, "--write", "--loglevel=error", "--"] + source_files,
-        shell=False,
-        quiet=True)
+    source_files = get_sources(root_path, ["*.js", "*.json", "*.ts", "*.md"])
+    if source_files:
+        print_command("prettier", source_files)
+        run(["node", script, "--write", "--loglevel=error", "--"] +
+            source_files,
+            shell=False,
+            quiet=True)
 
 
 def yapf():
-    print "yapf"
     script = os.path.join(third_party_path, "python_packages", "bin", "yapf")
-    source_files = git_ls_files(root_path, ["*.py"])
-    run([sys.executable, script, "-i", "--"] + source_files,
-        env=python_env(),
-        shell=False,
-        quiet=True)
+    source_files = get_sources(root_path, ["*.py"])
+    if source_files:
+        print_command("yapf", source_files)
+        run([sys.executable, script, "-i", "--style=pep8", "--"] +
+            source_files,
+            env=python_env(),
+            shell=False,
+            quiet=True)
 
 
 def rustfmt():
-    print "rustfmt"
     config_file = os.path.join(root_path, ".rustfmt.toml")
-    source_files = git_ls_files(root_path, ["*.rs"])
-    run([
-        "rustfmt",
-        "--config-path=" + config_file,
-        "--",
-    ] + source_files,
-        shell=False,
-        quiet=True)
+    source_files = get_sources(root_path, ["*.rs"])
+    if source_files:
+        print_command("rustfmt", source_files)
+        run([
+            "rustfmt",
+            "--config-path=" + config_file,
+            "--",
+        ] + source_files,
+            shell=False,
+            quiet=True)
 
 
 if __name__ == "__main__":
diff --git a/tools/lint.py b/tools/lint.py
index 2a01ffd5b8..86c45b5393 100755
--- a/tools/lint.py
+++ b/tools/lint.py
@@ -5,20 +5,39 @@
 import os
 import sys
 import argparse
-from util import enable_ansi_colors, git_ls_files, root_path, run
-from util import third_party_path, build_mode
+from util import enable_ansi_colors, git_ls_files, git_staged, root_path, run
+from util import third_party_path, build_mode, print_command
 from third_party import python_env
 
+cmd_args = None
+
+
+def get_cmd_args():
+    global cmd_args
+
+    if cmd_args:
+        return cmd_args
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument("--js", help="run eslint", action="store_true")
+    parser.add_argument("--py", help="run pylint", action="store_true")
+    parser.add_argument("--rs", help="run clippy", action="store_true")
+    parser.add_argument(
+        "--staged", help="run only on staged files", action="store_true")
+    cmd_args = parser.parse_args()
+    return cmd_args
+
+
+def get_sources(*args):
+    getter = git_staged if get_cmd_args().staged else git_ls_files
+    return getter(*args)
+
 
 def main():
     enable_ansi_colors()
     os.chdir(root_path)
 
-    parser = argparse.ArgumentParser()
-    parser.add_argument("--js", help="run eslint", action="store_true")
-    parser.add_argument("--py", help="run pylint", action="store_true")
-    parser.add_argument("--rs", help="run clippy", action="store_true")
-    args = parser.parse_args()
+    args = get_cmd_args()
 
     did_fmt = False
     if args.js:
@@ -38,36 +57,39 @@ def main():
 
 
 def eslint():
-    print "eslint"
     script = os.path.join(third_party_path, "node_modules", "eslint", "bin",
                           "eslint")
     # Find all *directories* in the main repo that contain .ts/.js files.
-    source_files = git_ls_files(root_path, [
+    source_files = get_sources(root_path, [
         "*.js", "*.ts", ":!:std/**/testdata/*", ":!:std/**/node_modules/*",
-        ":!:cli/compilers/*"
+        ":!:cli/compilers/wasm_wrap.js", ":!:cli/tests/error_syntax.js"
     ])
-    source_dirs = set([os.path.dirname(f) for f in source_files])
-    # Within the source dirs, eslint does its own globbing, taking into account
-    # the exclusion rules listed in '.eslintignore'.
-    source_globs = ["%s/*.{js,ts}" % d for d in source_dirs]
-    # Set NODE_PATH so we don't have to maintain a symlink in root_path.
-    env = os.environ.copy()
-    env["NODE_PATH"] = os.path.join(root_path, "third_party", "node_modules")
-    run(["node", script, "--max-warnings=0", "--"] + source_globs,
-        shell=False,
-        env=env,
-        quiet=True)
+    if source_files:
+        print_command("eslint", source_files)
+        # Set NODE_PATH so we don't have to maintain a symlink in root_path.
+        env = os.environ.copy()
+        env["NODE_PATH"] = os.path.join(root_path, "third_party",
+                                        "node_modules")
+        run(["node", script, "--max-warnings=0", "--"] + source_files,
+            shell=False,
+            env=env,
+            quiet=True)
 
 
 def pylint():
-    print "pylint"
     script = os.path.join(third_party_path, "python_packages", "pylint")
     rcfile = os.path.join(root_path, "tools", "pylintrc")
-    source_files = git_ls_files(root_path, ["*.py"])
-    run([sys.executable, script, "--rcfile=" + rcfile, "--"] + source_files,
-        env=python_env(),
-        shell=False,
-        quiet=True)
+    msg_template = "{path}({line}:{column}) {category}: {msg} ({symbol})"
+    source_files = get_sources(root_path, ["*.py"])
+    if source_files:
+        print_command("pylint", source_files)
+        run([
+            sys.executable, script, "--rcfile=" + rcfile,
+            "--msg-template=" + msg_template, "--"
+        ] + source_files,
+            env=python_env(),
+            shell=False,
+            quiet=True)
 
 
 def clippy():
diff --git a/tools/util.py b/tools/util.py
index c4aaa1e5b4..e5dcaccce0 100644
--- a/tools/util.py
+++ b/tools/util.py
@@ -193,6 +193,23 @@ def git_ls_files(base_dir, patterns=None):
     return files
 
 
+# list all files staged for commit
+def git_staged(base_dir, patterns=None):
+    base_dir = os.path.abspath(base_dir)
+    args = [
+        "git", "-C", base_dir, "diff", "--staged", "--diff-filter=ACMR",
+        "--name-only", "-z"
+    ]
+    if patterns:
+        args += ["--"] + patterns
+    output = subprocess.check_output(args)
+    files = [
+        os.path.normpath(os.path.join(base_dir, f)) for f in output.split("\0")
+        if f != ""
+    ]
+    return files
+
+
 # The Python equivalent of `rm -rf`.
 def rmtree(directory):
     # On Windows, shutil.rmtree() won't delete files that have a readonly bit.
@@ -406,3 +423,8 @@ def tty_capture(cmd, bytes_input, timeout=5):
         os.close(fd)  # can't do it sooner: it leads to errno.EIO error
     p.wait()
     return p.returncode, res['stdout'], res['stderr']
+
+
+def print_command(cmd, files):
+    noun = "file" if len(files) == 1 else "files"
+    print "%s (%d %s)" % (cmd, len(files), noun)