Overriding default key binding in XMonad - xmonad

Here is a very simple XMonad config I am starting with.
main :: IO ()
main = xmonad $ def
{ modMask = mod4Mask -- Rebind Mod to the Super key
terminal = "alacritty"
}
The only thing it does is:
Overrides the default modifier key.
Overrides the default terminal.
How can I override the keybinding for launching a terminal?
I am aware of the additionalKeysP thingy, it works, but it does not overrides the default keybindings, it just adds keybindings and I want to override the default instead of adding.
Please help :-)

It may not be straightforward, but you can overwrite default key like this:
`additionalKeysP`
[ ("M1-C-t", spawn "") -- Default key.
, ("M1-C-a", spawn "alacritty") -- New key for launching alacritty.
]
Function spawn "A" execute command A in a shell (e.g. spawn "ls -a" execute shell command ls -a). So you should rewrite spawn "alacritty" to your favorite code launching alacritty.
I don't know well about shell command for launching alacritty.
I'm assuming:
You are using modMask = mod4Mask in your xmonad.hs.
You know how to use additionalKeysP.
The default key is Alt+Ctrl+t for launching a terminal.
You want to launch a terminal by key Alt+Ctrl+a.
The shell command xmodmap output is like this (It's important Alt keys are contained group mod1 at now.):
$ xmodmap
xmodmap: up to 4 keys per modifier, (keycodes in parentheses):
shift Shift_L (0x32), Shift_R (0x3e)
...
mod1 Alt_L (0x40), Alt_R (0x6c), Alt_L (0xcc), Meta_L (0xcd)
...
mod4 Super_L (0x85), Super_R (0x86), Super_L (0xce), Hyper_L (0xcf)

Related

What's happening here with vim inside TMUX pane?

When I open vim inside of a TMUX pane, The pane is filled with codes I don't recognise. If I just run vim, I get this:
^[[38;2;165;42;42m 1
^[[38;2;0;0;255m~
If I open a file with vim, I get something like this (top pane):
Pretty new to both vim and TMUX. How can I solve this?
It seems that Vim is sending control sequences to your terminal which the latter doesn't understand.
More specifically, the sequences you mentioned in the OP:
^[[38;2;165;42;42m
^[[38;2;0;0;255m
look like they're encoding foreground true colors for the text.
You can find their syntax here:
CSI Pm m
Where CSI stands for “Control Sequence Introducer” and is produced by the keys ESC [, and Pm stands for:
A multiple numeric parameter composed of any number of single numeric parameters, separated by ; character(s).
If you scroll down the page, you should find a description of a more detailed syntax:
CSI Pm m Character Attributes (SGR).
...
This variation on ISO-8613-6 is supported for compatibility with KDE konsole:
Pm = 3 8 ; 2 ; Pr; Pg; Pb
Set foreground color to the closest match in xterm's palette for
the given RGB Pr/Pg/Pb.
Pm = 4 8 ; 2 ; Pr; Pg; Pb
Set background color to the closest match in xterm's palette for
the given RGB Pr/Pg/Pb.*
Applied to your first sequence, you can break it down like so:
┌ CSI
│ ┌ Pm
├─┐├────────────┐
^[[38;2;165;42;42m
├─┘ ├┘ ├┘
│ │ └ Pb = amount of blue
│ └ Pg = amount of green
└ Pr = amount of red
If the terminal doesn't understand this sequence, I can see 3 explanations:
the terminal doesn't support true colors
tmux is not properly configured to support true colors
Vim is not properly configured to support true colors
To test whether 1. is the issue, you can write this bash function in your ~/.bashrc:
truecolor() {
local i r g b
for ((i = 0; i <= 79; i++)); do
b=$((i*255/79))
g=$((2*b))
r=$((255-b))
if [[ $g -gt 255 ]]; then
g=$((2*255 - g))
fi
printf -- '\e[48;2;%d;%d;%dm \e[0m' "$r" "$g" "$b"
done
printf -- '\n'
}
Then execute $ truecolor in your shell, outside tmux. If you get some kind of rainbow, your terminal supports true colors (at least partially).
If you see some cells which are not colored, and others randomly colored, your terminal doesn't support true colors.
Alternatively, you can try the sequences manually:
$ printf '\e[38;2;%d;%d;%dm this text should be colored \e[0m' 165 42 42
$ printf '\e[38;2;%d;%d;%dm this text should be colored \e[0m' 0 0 255
If $ truecolor doesn't produce a rainbow, or if the $ printf commands don't change the foreground color (not the background color) of the text, you'll have to either:
disable 'termguicolors' in your ~/.vimrc; i.e. remove set termguicolors (or make it execute set notermguicolors)
try and upgrade your terminal
find another terminal which supports true colors
To test whether 2. is the issue, inside tmux, you can execute this shell command:
$ tmux info | grep Tc
If the output contains [missing]:
203: Tc: [missing]
^^^^^^^^^
it means that tmux is not configured to support true colors.
In this case, you have to include something like this in ~/.tmux.conf:
set -as terminal-overrides ',*-256color:Tc'
││ ├────────────────┘ ├────────┘ ├┘
││ │ │ └ tell tmux that the terminal suppors true colors
││ │ └ configure the option only if `$TERM` ends with the string `-256color`
││ └ the option to configure is `terminal-overrides` (see `$ man tmux`)
│└ the next option is a server option
└ append the value to the tmux option instead of overwriting it
Then restart tmux, and execute $ tmux info | grep Tc. This time the output should contain true:
203: Tc: (flag) true
^^^^
If it doesn't, have a look at the output of $TERM outside tmux:
$ echo $TERM
The output should be matched by whatever pattern you write before :Tc.
In the previous example, I used the pattern *-256color which will match any terminal whose $TERM ends with the string -256color. If it doesn't match your $TERM, you can try another pattern, or simply write * to describe any type of terminal:
set -as terminal-overrides ',*:Tc'
To test whether 3. is the issue, you can write these commands in your ~/.vimrc:
set termguicolors
let &t_8f = "\<Esc>[38:2:%lu:%lu:%lum"
let &t_8b = "\<Esc>[48:2:%lu:%lu:%lum"
Or:
set termguicolors
let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
The only difference between the 2 versions is the delimiter between the parameters of the sequences. A colon in the first version, a semicolon in the second one. See :h xterm-true-color for more info.
You can check the current values of these 3 options by executing successively:
:echo &tgc
:echo &t_8f
:echo &t_8b
They should output:
1
^[[38:2:%lu:%lu:%lum
^[[48:2:%lu:%lu:%lum
Or:
1
^[[38;2;%lu;%lu;%lum
^[[48;2;%lu;%lu;%lum

backspace not working in bash restricted mode

I am facing a problem with backspace in bash when used in restricted mode. I have already googled through lots of things, nothing worked or matching scenario am facing.
On pressing backspace, cursor is moving forward by one white space, but internally actually it's deleting the previous letter, i.e. on pressing "enter" it actually works but not visible on screen.
Example: command "ls backspace backspace", don't list anything (as expected) but on screen ls is visible after 2 backspaces and extra 2 white spaces are appended.
Looking forward for helpful suggestions. :)
Thanks in advance !! :)
Below is the piece of patch i used to chroot my bash.
Please have look and notify me if something is wrong here.
file: shell.c: ## -384,6 +387,30 ##
+ if (getcwd(pwd,sizeof(pwd)) != pwd )
+ {
+ return -1;
+ }
+ /* chroot to mount point path */
+ if( !(chroot(chroot_dir)))
+ {
+ seteuid(getuid());
+ setegid(getgid());
+ /* On successful to chroot env invoke bash prompt */
+ if(! chdir(pwd))
+ {
+ if(execlp("/rbin/bash","/rbin/bash","--restricted",NULL))
+ {
+ }
+ }
+ else
+ {
+ chdir("/");
+ if(execlp("/rbin/bash","/rbin/bash","--restricted",NULL))
+ {
+ }
+ }
+ }
Try using Backspace with Shift key, It should work.
If pressing backspace is printing a character, then you can use stty to change terminal settings like this: stty erase backspace_character where backspace_character is the character you get while pressing backspace.
you can use emacs command
for shell terminal you can hit command as below
set -o emacs
for vi editor you can hit command as below
set -o vi

How to send text to GHCi process?

I'm working on Haskell presentation engine Howerpoint. It is running in GHCi. I would like to create a function which would output a statement to current running GHCi session. It must work on Linux and Mac, Windows is not necessary. Function probably will have type
executeStatement :: String -> IO ()
What I tried already:
getProcessID and getParentProcessID and then sending something like
echo 'xxx' > /proc/92856/fd/1
-bash: /proc/92856/fd/1: No such file or directory
I also tried runCommand but it executes command in the Bash and not in GHCi so I got error that the command was not found
xdotool does not run on mac
You could use the ghcid project from hackage to evaluate expressions. They would not be evaluated in the same session as your are currently running, but you can send expressions and read their output in a session nonetheless.
Here is an example:
import Language.Haskell.Ghcid
main :: IO ()
main = do
(g, _) <- startGhci "ghci" (Just ".") True
let executeStatement = exec g
executeStatement "let x = 33"
executeStatement "x + 8" >>= print . head
executeStatement "print x" >>= print . head
stopGhci g
The output is "41" "33" and g represents a ghci session.
If you really need to execute expressions in an already running ghci instance you can have a look at this function - startGhci and instead of creating a new process you would have to tap into the existing process and then set std_in, std_out and std_err.
You could use a terminal multiplexer like tmux to execute ghci in one pane, and from another pane invoke tmux commands that send keystrokes to ghci.
tmux load-buffer lets you load text into a tmux clipboard (using - as the path reads from stdin).
# from within tmux
$ echo foo | tmux load-buffer -
$ tmux show-buffer
foo
tmux paste-buffer lets you paste the contents of a tmux clipboard into a pane:
$ tmux list-panes
0: [127x24] [history 1850/2000, 1343570 bytes] %0
1: [127x24] [history 0/2000, 0 bytes] %2 (active)
$ tmux paste-buffer -t %0
Another option, already mentioned in the comments, is to use the process library to launch a ghci process, and send the commands through piped stardard input.
Here's a small program that uses my process-streaming helper package for process (not really required, you could do the same using process alone). stdin is piped, stdout and stderr inherited:
{-# LANGUAGE OverloadedStrings #-}
import System.Process.Streaming -- from process-streaming
import Pipes (lift,yield) -- from pipes
import Control.Concurrent (threadDelay)
main :: IO ()
main = executeInteractive program (feedProducer (do
let delay = lift (threadDelay (1000000*6))
delay
yield "4 + 3\n"
delay
yield "5 + 3\n"))
where
program = (shell "ghci"){ std_in = CreatePipe }
The output is:
$ ./Main
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
Prelude> 7
Prelude> 8
Prelude> Leaving GHCi.

tmux: how to open file under cursor

i am a vim user and got used to the gf command, which opens the file under the cursor.
Now i wanted to ask, if there is something like that for tmux.
I can navigate through a tmux-pane and it happens often that there is a file-path under the cursor. Now i like to have the possibility to open that file under the cursor with vim.
A: in the current window
B: in another window which includes and opened vim
Maybe there is a possibility to run a sh-script in that navigation-mode when invoking a special key-combination? that would make it possible to write my own scripts like i got used to in vim with vimscript.
I am already using some vi-copy modes in mux .tmux.conf
# VIM
# ===================================================================
# Vimlike copy mode.
unbind [
bind Escape copy-mode
unbind p
bind p paste-buffer
bind -t vi-copy 'v' begin-selection
bind -t vi-copy 'y' copy-selection
# Enable vi keys.
setw -g mode-keys vi
# https://coderwall.com/p/4b0d0a/how-to-copy-and-paste-with-tmux-on-ubuntu
bind -t vi-copy y copy-pipe "xclip -sel clip -i"
I've been searching for an answer for years and ended up making a tmux plugin: https://github.com/artemave/tmux_super_fingers. It still baffles me how such in integral part of terminal based workflow is not a solved problem (well, it is now).
To achieve what you want, you need to use the stdin in your command line (xargs can do that) and tell tmux, in a new-window, to open the data with the arguments from the copy buffer:
bind -t vi-copy y copy-pipe "xargs -I{} tmux new-window 'vim {}'"
This needs more tuning (getting the right session, the right command, use $EDITOR instead of vim etc.
It is quite dangerous: Think copying /foo/bar/my;rm -rf /.
Also, as-is, this will only work for paths relative to tmux' working directory.
There's a mod for tmux allowing to bind an action of any complexity in 'mode': http://ershov.github.io/tmux/
There's an example of how to mark the word under cursor using that patch:
proc is_word_char {c} {
print [scan $c %c]
return [expr {$c > " " && $c != "\x7f"}]
}
proc mark-current-word {} {
clear-selection
set l [copy-mode-screenline]
set x [copy-mode-get-cx]
if {![is_word_char [string range $l $x $x]]} return
incr x
while {[is_word_char [string range $l $x $x]]} {
cursor-right
incr x
}
incr x -2
begin-selection
while {[is_word_char [string range $l $x $x]]} {
cursor-left
if {$x < 1} return
incr x -1
}
}
# Open selection in a vim mini-window (no shell and files)
bind-key -t vi-copy y tcl {
split-window -c [f #{pane_current_path}] -l 5 "
echo -n [shell-quote [copy-mode-selection]] | vim -R -"
}
Hence, to open the current file in vim:
mark-current-word
split-window -c [f #{pane_current_path}] -l 5 "vim -R [shell-quote [copy-mode-selection]]"
So i got it running with the following binding:
bind -t vi-copy y copy-pipe "xargs -I{} tmux send-keys -t 1 ';edit {}' Enter && tmux select-pane -t 1"
notes
i changed vim command : to ;
i have a open vim in pane 1

Configure vimrc based on environment variables

Is it possible to configure vimrc command mapping based on env variables?
For example, I'm using vim-ruby-test plugin which provides the following config:
let g:rubytest_cmd_test = "ruby %p"
I want to set the command differently based on whether i'm running tests using spork or not:
With Spork:
$ TESTDRB=y mvim .
let g:rubytest_cmd_test = "testdrb %p"
Without Spork:
$ mvim .
let g:rubytest_cmd_test = "ruby %p"
if $TESTDRB == 'y'
let g:rubytest_cmd_test = 'ruby %p'
endif
" etc

Resources