mirror of
				https://github.com/occivink/kakoune-sudo-write
				synced 2025-10-05 23:11:09 +02:00 
			
		
		
		
	Refactor plugin to not rely on caching for writing anymore
Also test if the buffer is backed by a file, and fail if not
This commit is contained in:
		
							parent
							
								
									f9bbf4606b
								
							
						
					
					
						commit
						9a11b5c8c2
					
				| @ -10,8 +10,6 @@ Add `sudo-write.kak` to your autoload dir: `~/.config/kak/autoload/`, or source | ||||
| 
 | ||||
| Call the `sudo-write` command. If your password has not been cached by `sudo`, you will be prompted to input it. Upon success, the buffer is written to the file. | ||||
| 
 | ||||
| Note that the plugin will not work if you do not use any cache for `sudo`. | ||||
| 
 | ||||
| **Warning**: while the input is hidden, the password is still passed through stdin to `sudo`. Do not use this plugin if you are not comfortable with this idea. | ||||
| 
 | ||||
| ## License | ||||
|  | ||||
| @ -1,9 +1,9 @@ | ||||
| # save the current buffer to its file as root | ||||
| # save the current buffer to its file as root using `sudo` | ||||
| # (optionally pass the user password to sudo if not cached) | ||||
| 
 | ||||
| define-command -hidden sudo-write-impl %{ | ||||
| define-command -hidden sudo-write-cached-password %{ | ||||
|     # easy case: the password was already cached, so we don't need any tricky handling | ||||
|     eval -save-regs f %{ | ||||
|         # TOOD this could take the content of the buffer from stdin instead | ||||
|         reg f %sh{ mktemp --tmpdir XXXXX } | ||||
|         write %reg{f} | ||||
|         eval %sh{ | ||||
| @ -11,49 +11,60 @@ define-command -hidden sudo-write-impl %{ | ||||
|             if [ $? -eq 0 ]; then | ||||
|                 echo "edit!" | ||||
|             else | ||||
|                 echo "echo -markup '{Error}Something went wrong'" | ||||
|                 echo 'fail "Unknown failure"' | ||||
|             fi | ||||
|             rm -f "$kak_main_reg_f" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| define-command -hidden -params 1 sudo-cache-password %{ | ||||
|     eval -no-hooks -save-regs '"c' %{ | ||||
|         eval -draft %{ | ||||
|             edit -scratch *sudo-write-pass* | ||||
|             reg '"' %arg{1} | ||||
|             exec "<a-p>|sudo -S echo ok<ret>" | ||||
|             try %{ | ||||
|                 exec '%H<a-k>ok<ret>' | ||||
|                 reg c nop | ||||
|             } catch %{ | ||||
|                 reg c fail | ||||
|             } | ||||
|         } | ||||
|         delete-buffer *sudo-write-pass* | ||||
|         eval %reg{c} | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| define-command -hidden sudo-prompt-password %{ | ||||
| define-command -hidden sudo-write-prompt-password %{ | ||||
|     prompt -password 'Password:' %{ | ||||
|         try %{ | ||||
|             sudo-cache-password %val{text} | ||||
|             sudo-write-impl | ||||
|         } catch %{ | ||||
|             echo -markup '{Error}Incorrect password' | ||||
|         eval -save-regs r %{ | ||||
|             eval -draft -save-regs 'tf|"' %{ | ||||
|                 reg t %val{buffile} | ||||
|                 reg f %sh{ mktemp --tmpdir XXXXX } | ||||
|                 write %reg{f} | ||||
| 
 | ||||
|                 # write the password in a buffer in order to pass it through STDIN to sudo | ||||
|                 # somewhat dangerous, but better than passing the password | ||||
|                 # through the shell scope's environment or interpolating it inside the shell string | ||||
|                 # 'exec |' is pretty much the only way to pass data over STDIN | ||||
|                 edit -scratch '*sudo-password-tmp*' | ||||
|                 reg '"' "%val{text}" | ||||
|                 exec <a-P> | ||||
|                 reg | %{ | ||||
|                     sudo -S -- dd if="$kak_main_reg_f" of="$kak_main_reg_t" > /dev/null 2>&1 | ||||
|                     if [ $? -eq 0 ]; then | ||||
|                         printf 'edit!' | ||||
|                     else | ||||
|                         printf 'fail "Incorrect password?"' | ||||
|                     fi | ||||
|                     rm -f "$kak_main_reg_f" | ||||
|                 } | ||||
|                 exec '|<ret>' | ||||
|                 exec -save-regs '' '%"ry' | ||||
|                 delete-buffer! '*sudo-password-tmp*' | ||||
|             } | ||||
|             eval %reg{r} | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| define-command sudo-write -docstring "Write the content of the buffer using sudo" %{ | ||||
|     %sh{ | ||||
|     eval %sh{ | ||||
|         # tricky posix-way of getting the first character of a variable | ||||
|         # no subprocess! | ||||
|         if [ "${kak_buffile%"${kak_buffile#?}"}" != "/" ]; then | ||||
|             # not entirely foolproof as a scratch buffer may start with '/', but good enough | ||||
|             printf 'fail "Not a file"' | ||||
|             exit | ||||
|         fi | ||||
|         # check if the password is cached | ||||
|         if sudo -n true > /dev/null 2>&1; then | ||||
|             echo sudo-write-impl | ||||
|             printf sudo-write-cached-password | ||||
|         else | ||||
|             echo sudo-prompt-password | ||||
|             printf sudo-write-prompt-password | ||||
|         fi | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Olivier Perret
						Olivier Perret