├── ssh ├── requirements.txt ├── README.md └── check.py └── helix ├── runtime └── queries │ ├── go │ └── injections.scm │ ├── markdown │ └── injections.scm │ └── python │ └── injections.scm ├── languages.toml ├── .tmux.conf └── config.toml /ssh/requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | paramiko 3 | -------------------------------------------------------------------------------- /ssh/README.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | 3 | A script that checks SSH access given a public key. 4 | 5 | Read more: https://rushter.com/blog/public-ssh-keys/ 6 | 7 | ```bash 8 | $ pip install requests paramiko 9 | ``` 10 | 11 | 12 | # Usage 13 | 14 | 15 | ```bash 16 | $ python check.py example.org --github-username example --ssh-username root 17 | ``` 18 | 19 | -------------------------------------------------------------------------------- /helix/runtime/queries/go/injections.scm: -------------------------------------------------------------------------------- 1 | 2 | 3 | (([ 4 | (interpreted_string_literal_content) 5 | (raw_string_literal_content) 6 | ] @injection.content 7 | (#match? @injection.content "(?ism)(SELECT|select|INSERT|insert|UPDATE|update|DELETE|delete).+(FROM|from|INTO|into|VALUES|values|SET|set).*(WHERE|where|GROUP BY|group by)?") 8 | ) 9 | (#set! injection.language "sql") 10 | ) 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /helix/runtime/queries/markdown/injections.scm: -------------------------------------------------------------------------------- 1 | (fenced_code_block 2 | (info_string 3 | (language) @injection.language) 4 | (code_fence_content) @injection.content) 5 | 6 | ((html_block) @injection.content (#set! injection.language "html")) 7 | 8 | (document . (section . (thematic_break) (_) @injection.content (thematic_break)) (#set! injection.language "yaml")) 9 | 10 | ((minus_metadata) @injection.content (#set! injection.language "yaml")) 11 | -------------------------------------------------------------------------------- /helix/runtime/queries/python/injections.scm: -------------------------------------------------------------------------------- 1 | (call 2 | function: (attribute 3 | object: (identifier) @py_object 4 | attribute: (identifier) @py_function) 5 | (#match? @py_function "^execute") 6 | (#match? @py_object ".*(cur|conn)(ection)?$") 7 | arguments: (argument_list 8 | (string 9 | (string_content) @injection.content)) 10 | (#set! injection.language "sql")) @python_highlight_sqlite 11 | 12 | (call 13 | function: (attribute 14 | object: (identifier) @py_object 15 | attribute: (identifier) @py_function) 16 | (#eq? @py_object "shlex") 17 | (#eq? @py_function "split") 18 | arguments: (argument_list 19 | (string 20 | (string_content) @injection.content)) 21 | (#set! injection.language "bash")) @python_highlight_shlex 22 | 23 | ((string_content) @injection.content 24 | (#match? @injection.content 25 | "(?ism)^(SELECT|INSERT|UPDATE|DELETE).*?(FROM|INTO|VALUES|SET)(.|\n)*?(WHERE|GROUP BY)?") 26 | (#set! injection.language "sql")) 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /helix/languages.toml: -------------------------------------------------------------------------------- 1 | 2 | [language-server.harper-ls] 3 | command = "harper-ls" 4 | args = ["--stdio"] 5 | 6 | 7 | [[language]] 8 | name = "markdown" 9 | language-servers = ["harper-ls"] 10 | 11 | 12 | [language-server.ruff] 13 | command = "ruff" 14 | args = ["server"] 15 | 16 | [language-server.ruff.config] 17 | documentFormatting = true 18 | settings.run = "onSave" 19 | 20 | [language-server.pyright] 21 | command = "pyright-langserver" 22 | args = ["--stdio"] 23 | config.reportMissingtypeStubs = false 24 | 25 | [[language]] 26 | name = "python" 27 | auto-format = true 28 | language-servers = [ 29 | { name = "ruff" }, 30 | { name = "zuban" }, 31 | { name = "harper-ls" }, 32 | { name = "codebook" }, 33 | ] 34 | roots = ["pyproject.toml", "setup.py", "poetry.lock", ".git", ".jj", ".venv/"] 35 | 36 | 37 | [language-server.zuban] 38 | command = "zuban" 39 | args = ["server"] 40 | 41 | [language-server.basedpyright] 42 | command = "basedpyright-langserver" 43 | args = ["--stdio"] 44 | 45 | [language-server.basedpyright.config.python.analysis] 46 | typeCheckingMode = "standard" 47 | 48 | 49 | [[language]] 50 | name = "rust" 51 | language-servers = ["rust-analyzer", "harper-ls", "codebook"] 52 | 53 | [language-server.rust-analyzer.config] 54 | cargo.features = "all" 55 | check.command = "clippy" 56 | 57 | 58 | [[language]] 59 | name = "sql" 60 | formatter = { command = "sqlfluff", args = [ 61 | "format", 62 | "--dialect", 63 | "clickhouse", 64 | '-e', 65 | 'CP02', 66 | '-', 67 | ] } 68 | 69 | 70 | 71 | [[language]] 72 | name = "cython" 73 | language-servers = [ 74 | { name = "harper-ls" }, 75 | ] 76 | 77 | 78 | [language-server.yaml-language-server.config.yaml] 79 | completion = true 80 | validate = true 81 | hover = true 82 | format = { enable = true, bracketSpacing = true } 83 | schemas = [] 84 | schemaStore = { enable = false } 85 | 86 | 87 | [language-server.codebook] 88 | command = "codebook-lsp" 89 | args = ["serve"] 90 | -------------------------------------------------------------------------------- /helix/.tmux.conf: -------------------------------------------------------------------------------- 1 | set -g mouse off 2 | 3 | 4 | setw -g mode-style 'fg=black bg=blue bold' 5 | setw -g clock-mode-colour yellow 6 | 7 | set -g pane-border-style 'fg=red' 8 | set -g pane-active-border-style 'fg=yellow' 9 | 10 | set -g status-position bottom 11 | set -g status-justify left 12 | set -g status-style 'fg=red' 13 | set -g status-left '' 14 | set -g status-left-length 30 15 | 16 | set -g status-right-style 'fg=black bg=yellow' 17 | set -g status-right '%Y-%m-%d %H:%M ' 18 | set -g status-right-length 0 19 | 20 | setw -g window-status-current-style 'fg=black bg=blue' 21 | setw -g window-status-current-format ' #I #W #F ' 22 | 23 | setw -g window-status-style 'fg=red bg=black' 24 | setw -g window-status-format ' #I #[fg=white]#W #[fg=yellow]#F ' 25 | 26 | setw -g window-status-bell-style 'fg=yellow bg=red bold' 27 | 28 | set -g message-style 'fg=yellow bg=red bold' 29 | 30 | set -g status-justify centre 31 | 32 | 33 | 34 | set-option -g prefix 'C-\' 35 | set-option -g prefix2 C-b 36 | 37 | set -g history-limit 1000000 38 | 39 | bind-key J resize-pane -D 5 40 | bind-key K resize-pane -U 5 41 | bind-key H resize-pane -L 5 42 | bind-key L resize-pane -R 5 43 | 44 | bind-key M-j resize-pane -D 45 | bind-key M-k resize-pane -U 46 | bind-key M-h resize-pane -L 47 | bind-key M-l resize-pane -R 48 | 49 | bind h select-pane -L 50 | bind j select-pane -D 51 | bind k select-pane -U 52 | bind l select-pane -R 53 | 54 | 55 | bind-key v split-window -v -c "#{pane_current_path}" 56 | bind-key s split-window -h -c "#{pane_current_path}" 57 | 58 | setw -g mode-keys vi 59 | bind r source-file ~/.tmux.conf 60 | 61 | set-option -g status-right "" 62 | 63 | set -g status-left '#[fg=green]#S-#(whoami) #H' 64 | 65 | set -g base-index 1 66 | 67 | bind r source-file ~/.tmux.conf \; display "Reloaded!" 68 | 69 | bind-key / copy-mode \; send-key ? 70 | 71 | unbind -T copy-mode-vi Enter 72 | unbind -T copy-mode-vi Space 73 | 74 | bind-key -T edit-mode-vi Up send-keys -X history-up 75 | bind-key -T edit-mode-vi Down send-keys -X history-down 76 | 77 | bind-key -T copy-mode-vi 'v' send-keys -X begin-selection 78 | 79 | bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel 80 | set -ga terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[2 q' 81 | 82 | set -g default-terminal "xterm-256color" 83 | 84 | 85 | bind-key y display-popup -d '#{pane_current_path}' -x R -h 95% -w 95% -E 'tmux new-session yazi \; set status off' 86 | bind-key g popup -E -w 95% -h 95% -d '#{pane_current_path}' lazygit 87 | 88 | set -g allow-passthrough on 89 | set -ga update-environment TERM 90 | set -ga update-environment TERM_PROGRAM 91 | 92 | bind c new-window -c "#{pane_current_path}" 93 | 94 | bind-key z popup -E -w 95% -h 90% 95 | 96 | 97 | set -q -g status-utf8 on 98 | setw -q -g utf8 on 99 | 100 | set -s escape-time 50 101 | 102 | set -g focus-events on 103 | 104 | bind-key e display-popup -w 95% -h 90% -E "tmux capture-pane -Jp -S- | hx -" 105 | -------------------------------------------------------------------------------- /helix/config.toml: -------------------------------------------------------------------------------- 1 | 2 | theme = "catppuccin_frappe" 3 | 4 | [editor] 5 | line-number = "relative" 6 | mouse = true 7 | rulers = [120] 8 | true-color = true 9 | completion-replace = true 10 | trim-trailing-whitespace = true 11 | end-of-line-diagnostics = "hint" 12 | color-modes = true 13 | rainbow-brackets = true 14 | 15 | [editor.inline-diagnostics] 16 | cursor-line = "warning" 17 | 18 | [editor.lsp] 19 | display-inlay-hints = false 20 | 21 | [editor.cursor-shape] 22 | insert = "bar" 23 | normal = "block" 24 | select = "underline" 25 | 26 | [editor.file-picker] 27 | hidden = false 28 | 29 | [editor.indent-guides] 30 | render = true 31 | character = "╎" 32 | skip-levels = 0 33 | 34 | [editor.soft-wrap] 35 | enable = false 36 | 37 | [keys.normal."+"] 38 | f = ":format" 39 | w = ":toggle whitespace.render all" 40 | W = ":set whitespace.render none" 41 | s = ":toggle soft-wrap.enable" 42 | 43 | [keys.normal."="] 44 | "=" = ":format" 45 | 46 | [editor.statusline] 47 | left = [ 48 | "mode", 49 | "spinner", 50 | "version-control", 51 | "spacer", 52 | "separator", 53 | "file-name", 54 | "read-only-indicator", 55 | "file-modification-indicator", 56 | 57 | ] 58 | center = [] 59 | right = [ 60 | "diagnostics", 61 | "workspace-diagnostics", 62 | "position", 63 | "total-line-numbers", 64 | "position-percentage", 65 | "file-encoding", 66 | "file-line-ending", 67 | "file-type", 68 | "register", 69 | "selections", 70 | ] 71 | separator = "│" 72 | mode.normal = "NOR" 73 | mode.insert = "INS" 74 | mode.select = "SEL" 75 | 76 | [keys.normal] 77 | D = ["ensure_selections_forward", "extend_to_line_end", "delete_selection"] 78 | 0 = "goto_line_start" 79 | "$" = "goto_line_end" 80 | "^" = "goto_first_nonwhitespace" 81 | G = "goto_file_end" 82 | V = ["select_mode", "extend_to_line_bounds"] 83 | esc = ["collapse_selection", "keep_primary_selection"] 84 | "Cmd-s" = ":write" 85 | 86 | 87 | [keys.normal.space] 88 | e = { w = ":write", c = ":bc", x = ":bco", l = ":toggle lsp.display-inlay-hints" } 89 | q = ":quit" 90 | 91 | [keys.normal.space.f] 92 | f = "file_picker_in_current_directory" 93 | F = "file_picker" 94 | b = "file_picker_in_current_buffer_directory" 95 | "." = ":toggle-option file-picker.git-ignore" 96 | g = "global_search" 97 | e = "file_explorer" 98 | r = ":reload-all" 99 | x = ":reset-diff-change" 100 | d = [":vsplit-new", ":lang diff", ":insert-output git diff"] 101 | 102 | [keys.select] 103 | 0 = "goto_line_start" 104 | "$" = "goto_line_end" 105 | "^" = "goto_first_nonwhitespace" 106 | G = "goto_file_end" 107 | D = ["extend_to_line_bounds", "delete_selection", "normal_mode"] 108 | k = ["extend_line_up", "extend_to_line_bounds"] 109 | j = ["extend_line_down", "extend_to_line_bounds"] 110 | up = ["extend_line_up", "extend_to_line_bounds"] 111 | down = ["extend_line_down", "extend_to_line_bounds"] 112 | 113 | [keys.select.space.f] 114 | s = ":reflow 100" 115 | 116 | [editor.auto-save] 117 | focus-lost = true 118 | after-delay.enable = true 119 | after-delay.timeout = 300000 120 | -------------------------------------------------------------------------------- /ssh/check.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import socket 3 | import sys 4 | 5 | import paramiko.auth_handler 6 | import requests 7 | import argparse 8 | 9 | 10 | def valid(self, msg): 11 | self.auth_event.set() 12 | self.authenticated = True 13 | print("Valid key") 14 | 15 | 16 | def parse_service_accept(self, m): 17 | # https://tools.ietf.org/html/rfc4252#section-7 18 | service = m.get_text() 19 | if not (service == "ssh-userauth" and self.auth_method == "publickey"): 20 | return self._parse_service_accept(m) 21 | m = paramiko.message.Message() 22 | m.add_byte(paramiko.common.cMSG_USERAUTH_REQUEST) 23 | m.add_string(self.username) 24 | m.add_string("ssh-connection") 25 | m.add_string(self.auth_method) 26 | m.add_boolean(False) 27 | m.add_string(self.private_key.public_blob.key_type) 28 | m.add_string(self.private_key.public_blob.key_blob) 29 | self.transport._send_message(m) 30 | 31 | 32 | def patch_paramiko(): 33 | table = paramiko.auth_handler.AuthHandler._client_handler_table 34 | 35 | # In order to avoid using a private key, two callbacks must be patched. 36 | # The MSG_USERAUTH_INFO_REQUEST (SSH_MSG_USERAUTH_PK_OK 60) indicates a valid public key. 37 | table[paramiko.common.MSG_USERAUTH_INFO_REQUEST] = valid 38 | # The MSG_SERVICE_ACCEPT event triggers when server sends a request for auth. 39 | # By default, paramiko signs it with the private key. We don't want that. 40 | table[paramiko.common.MSG_SERVICE_ACCEPT] = parse_service_accept 41 | 42 | 43 | def probe_host(hostname_or_ip, port, username, public_key): 44 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 45 | sock.connect((hostname_or_ip, port)) 46 | transport = paramiko.transport.Transport(sock) 47 | transport.start_client() 48 | 49 | # For compatibility with paramiko, we need to generate a random private key and replace 50 | # the public key with our data. 51 | key = paramiko.RSAKey.generate(2048) 52 | key.public_blob = paramiko.pkey.PublicBlob.from_string(public_key) 53 | try: 54 | transport.auth_publickey(username, key) 55 | except paramiko.ssh_exception.AuthenticationException: 56 | print("Bad key") 57 | 58 | 59 | def get_public_key(username): 60 | r = requests.get('https://github.com/%s.keys' % username) 61 | return r.content.decode('utf-8').splitlines() 62 | 63 | 64 | def main(): 65 | parser = argparse.ArgumentParser() 66 | parser.add_argument('host', type=str, help='Hostname or IP address') 67 | parser.add_argument('--github-username', type=str, default=None) 68 | parser.add_argument('--ssh-username', type=str, default="root") 69 | parser.add_argument('--loglevel', default='INFO') 70 | parser.add_argument('--port', type=int, default=22) 71 | parser.add_argument('--public-key', type=str, default=None) 72 | 73 | args = parser.parse_args(sys.argv[1:]) 74 | logging.basicConfig(level=args.loglevel) 75 | if args.github_username: 76 | keys = get_public_key(args.github_username) 77 | elif args.public_key: 78 | keys = [open(args.public_key, 'rt').read()] 79 | else: 80 | raise ValueError("Public key is missing. Please use --github-username or --public-key") 81 | 82 | for key in keys: 83 | patch_paramiko() 84 | probe_host( 85 | hostname_or_ip=args.host, 86 | port=args.port, 87 | username=args.ssh_username, 88 | public_key=key 89 | ) 90 | 91 | 92 | if __name__ == '__main__': 93 | main() 94 | --------------------------------------------------------------------------------