sudo update-alternatives --install /usr/bin/x-www-browser x-www-browser /usr/local/bin/surf 10
sudo update-alternatives --config x-www-browser
# for Debian / Devuan
# GTK3, WebKit2GTK, GCR
sudo apt install --no-install-recommends build-essential patch libwebkit2gtk-4.0-dev libgcr-3-dev
about:blank
)を設定。讀込中に表示されるページとは別らしい
對象バージョン:2.1
dmenu
で Fcitx が機能しないため、zenity
(GTK ダイアログ)を入力に使用してゐる (Since fcitx
does not work in dmenu
, I use zenity
instead.)
suckless-tools
44-1
; dmenu-4.8
fcitx
1:4.2.9.6-5+deb10u1
config.h
:
static int surfuseragent = 0;
static char *fulluseragent = "Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0";
[AccessMicrophone] = { { .i = 0 }, },
[AccessWebcam] = { { .i = 0 }, },
[Certificate] = { { .i = 0 }, },
[CaretBrowsing] = { { .i = 0 }, },
[CookiePolicies] = { { .v = "a" }, },
[DefaultCharset] = { { .v = "UTF-8" }, },
[DiskCache] = { { .i = 1 }, },
[DNSPrefetch] = { { .i = 0 }, },
[Ephemeral] = { { .i = 0 }, },
[FileURLsCrossAccess] = { { .i = 0 }, },
[FontSize] = { { .i = 16 }, },
[FrameFlattening] = { { .i = 0 }, },
[Geolocation] = { { .i = 0 }, },
[HideBackground] = { { .i = 0 }, },
[Inspector] = { { .i = 1 }, },
[Java] = { { .i = 0 }, },
[JavaScript] = { { .i = 0 }, },
[KioskMode] = { { .i = 0 }, },
[LoadImages] = { { .i = 1 }, },
[MediaManualPlay] = { { .i = 1 }, },
[PreferredLanguages] = { { .v = (char *[]){ "ja_JP", "en_US", NULL } }, },
[RunInFullscreen] = { { .i = 0 }, },
[ScrollBars] = { { .i = 1 }, },
[ShowIndicators] = { { .i = 0 }, },
[SiteQuirks] = { { .i = 1 }, },
[SmoothScrolling] = { { .i = 0 }, },
[SpellChecking] = { { .i = 0 }, },
[SpellLanguages] = { { .v = ((char *[]){ NULL }) }, },
[StrictTLS] = { { .i = 1 }, },
[Style] = { { .i = 1 }, },
[WebGL] = { { .i = 0 }, },
[ZoomLevel] = { { .f = 1.26 }, },
[TopDataURLs] = { { .i = 0 }, },
[Accelerated2DCanvas] = { { .i = 0 }, },
[HyperlinkAuditing] = { { .i = 0 }, },
[JavascriptMarkup] = { { .i = 0 }, },
[Media] = { { .i = 0 }, },
[OfflineCache] = { { .i = 0 }, },
[Plugin] = { { .i = 0 }, },
[WebAudio] = { { .i = 0 }, },
[ZoomTextOnly] = { { .i = 0 }, },
[PageCache] = { { .i = 1 }, },
[XssAuditor] = { { .i = 1 }, },
surf.c
(53, 273行目〜):
TopDataURLs,
Accelerated2DCanvas,
HyperlinkAuditing,
JavascriptMarkup,
Media,
OfflineCache,
Plugin,
WebAudio,
ZoomTextOnly,
PageCache,
XssAuditor,
surf.c
(746行目〜):
case FontSize:
webkit_settings_set_default_font_size(s, a->i);
webkit_settings_set_minimum_font_size(s, a->i);
webkit_settings_set_default_monospace_font_size(s, a->i);
return; /* do not update */
case TopDataURLs:
webkit_settings_set_allow_top_navigation_to_data_urls(s, a->i);
return; /* do not update */
case Accelerated2DCanvas:
webkit_settings_set_enable_accelerated_2d_canvas(s, a->i);
return; /* do not update */
case HyperlinkAuditing:
webkit_settings_set_enable_hyperlink_auditing(s, a->i);
return; /* do not update */
case JavascriptMarkup:
webkit_settings_set_enable_javascript_markup(s, a->i);
return; /* do not update */
case Media:
webkit_settings_set_enable_media(s, a->i);
webkit_settings_set_enable_media_capabilities(s, a->i);
webkit_settings_set_enable_media_stream(s, a->i);
webkit_settings_set_enable_mediasource(s, a->i);
return; /* do not update */
case OfflineCache:
webkit_settings_set_enable_offline_web_application_cache(s, a->i);
return; /* do not update */
case Plugin:
webkit_settings_set_enable_plugins(s, a->i);
return; /* do not update */
case WebAudio:
webkit_settings_set_enable_webaudio(s, a->i);
return; /* do not update */
case ZoomTextOnly:
webkit_settings_set_zoom_text_only(s, a->i);
return; /* do not update */
case PageCache:
webkit_settings_set_enable_page_cache(s, a->i);
return; /* do not update */
case XssAuditor:
webkit_settings_set_enable_xss_auditor(s, a->i);
return; /* do not update */
surf.c
(1103行目〜):
"allow-top-navigation-to-data-urls", curconfig[TopDataURLs].val.i,
"enable-accelerated-2d-canvas", curconfig[Accelerated2DCanvas].val.i,
"enable-hyperlink-auditing", curconfig[HyperlinkAuditing].val.i,
"enable-javascript-markup", curconfig[JavascriptMarkup].val.i,
"enable-media", curconfig[Media].val.i,
"enable-media-capabilities", curconfig[Media].val.i,
"enable-media-stream", curconfig[Media].val.i,
"enable-mediasource", curconfig[Media].val.i,
"enable-offline-web-application-cache", curconfig[OfflineCache].val.i,
"enable-plugins", curconfig[Plugin].val.i,
"enable-webaudio", curconfig[WebAudio].val.i,
"zoom-text-only", curconfig[ZoomTextOnly].val.i,
"enable-page-cache", curconfig[PageCache].val.i,
"enable-xss-auditor", curconfig[XssAuditor].val.i,
"minimum-font-size", curconfig[FontSize].val.i,
"default-monospace-font-size", curconfig[FontSize].val.i,
DiskCache
を無效にすると、ユーザースタイルシートが無效になる
zenity
から現在の URL を編輯して移動 (Edit and move the URL in zenity
)config.h
:
/* (zenity: GTK ダイアログから)現在の URL を編輯して移動 */
/* EDITURL(readprop, setprop) */
#define EDITURL(r, s) { \
.v = (const char *[]){ "/bin/sh", "-c", \
"prop=\"$(printf '%b' \"$(xprop -id $1 $2 " \
"| sed \"s/^$2(STRING) = //;s/^\\\"\\(.*\\)\\\"$/\\1/\")\"" \
")\" && input=\"$(zenity --entry --width=800 --height=20 --text=\"移動:\" --title=\"surf: 移動先を入力\" --entry-text=\"$prop\"" \
")\" && xprop -id $1 -f $3 8s -set $3 \"$input\"", \
"surf-setprop", winid, r, s, NULL \
} \
}
{ MODKEY, GDK_KEY_g, spawn, EDITURL("_SURF_URI", "_SURF_GO") },
dmenu
でも Tab → 編輯 → Shift + Enter で入力できるんだけど、やつぱり日本語が入力できないので
config.h
:
/* (zenity: GTK ダイアログから)現在の URL を編輯して移動 */
/* EDITURL(readprop, setprop) */
#define EDITURL(r, s) { \
.v = (const char *[]){ "/bin/sh", "-c", \
"prop=\"$(printf '%b' \"$(xprop -id $1 $2 " \
"| sed \"s/^$2(STRING) = //;s/^\\\"\\(.*\\)\\\"$/\\1/\")\"" \
")\" && input=\"$(zenity --entry --width=800 --height=20 --text=\"移動:\" --title=\"surf: 移動先を入力\" --entry-text=\"$prop\" | sed -E 's/^\\s+//g; s/\\s+$//g' " \
")\" && if [ \"$input\" ]; then " \
"input=\"$(echo \"$input\" " \
"| sed -E 's/^p( +(.+))*$/https:\\/\\/pkginfo.devuan.org\\/cgi-bin\\/policy-query.html?c=package\\&q=\\2/g' " \
"| sed -E 's/^dp( +(.+))*$/https:\\/\\/packages.debian.org\\/search?keywords=\\2\\&searchon=names\\&suite=stable\\§ion=main/g' " \
"| sed -E 's/^(.+\\.(com|info|net|org|(.+\\.)*jp)\\/*)$/https:\\/\\/\\1/g; s/^(https*:\\/\\/){2,}/\\1/g' " \
"| sed -E 's/^surf$/https:\\/\\/surf.suckless.org\\//g'" \
")\" && echo \"$input\" | grep -E '^[^:/]+://' " \
"|| input=\"$(echo \"$input\" | sed -E 's/^/https:\\/\\/search.disroot.org\\/?q=/g')\" " \
"&& xprop -id $1 -f $3 8s -set $3 \"$input\"; fi", \
"surf-setprop", winid, r, s, NULL \
} \
}
https*://
)以外の入力のフォールバックは無し。空白(入力のキャンセル)の處理が解らなかつた'
)のエスケープを削除
if [ \"$input\" ]; then
:空入力のフォールバック
echo \"$input\" | grep -E '^[^:/]+://'
:プロトコルのフォールバック。最短一致(といふか :/
ではない文字列の檢索)を知るのに苦勞した
&&
や ||
は直前のコマンドの眞僞しか判斷しないので if
に。if
は分岐から漏れたら何もしないので意圖した通りに實行できる
if
を一行で書くのは難しい。改行では不要なセミコロン(;
)を忘れがち
zenity
からページ內檢索 (Find the page in zenity
)config.h
:
/* (zenity: GTK ダイアログから)ページ内検索 */
/* FIND(setprop) */
#define FIND(s) { \
.v = (const char *[]){ "/bin/sh", "-c", \
"prop=\"$(zenity --entry --width=400 --height=20 --text=\"檢索:\" --title=\"surf: ページ內檢索\"" \
")\" && xprop -id $1 -f $2 8s -set $2 \"$prop\"", \
"surf-setprop", winid, s, NULL \
} \
}
{ MODKEY, GDK_KEY_slash, spawn, FIND("_SURF_FIND") },
dzen2
へ現在の URL を表示 (Show the URL in dzen2
)config.h
:
/* (dzen2 へ)現在の URL を表示 */
/* SHOWURL(readprop) */
#define SHOWURL(r) { \
.v = (const char *[]){ "/bin/sh", "-c", \
"prop=\"$(printf '%b' \"$(xprop -id $1 $2 " \
"| sed \"s/^$2(STRING) = //;s/^\\\"\\(.*\\)\\\"$/\\1/\")\"" \
")\" && echo \"$prop\" | dzen2 -ta l -p 4 -y -1 -bg '#204010' -fg '#a0d060' -fn 'monospace-18'", \
"surf-setprop", winid, r, NULL \
} \
}
{ MODKEY, GDK_KEY_w, spawn, SHOWURL("_SURF_URI") },
xprop
(デフォルトのコード)經由だとフラグメント識別子(#hoge
)は讀まない。Ctrl + Y(ステータステキストのコピー)だと認識するのだが
'
)のエスケープを削除
dzen2
へステータスを表示 (Show status in dzen2
)config.h
:
/* (dzen2 へ)ステータスを表示 */
/* SHOWSTATUS() */
#define SHOWSTATUS() { \
.v = (const char *[]){ "/bin/sh", "-c", \
"xdotool key --clearmodifiers ctrl+y " \
"&& echo \"$(xclip -selection c -o)\" | dzen2 -ta l -p 4 -y -1 -bg '#301000' -fg '#b09060' -fn 'monospace-18'", \
NULL \
} \
}
{ MODKEY, GDK_KEY_q, spawn, SHOWSTATUS() },
'
)のエスケープを削除
config.h
:
/* ページへのリンク(HTML)をコピー */
/* COPYLINK(readprop) */
#define COPYLINK(r) { \
.v = (const char *[]){ "/bin/sh", "-c", \
"prop=\"$(printf '%b' \"$(xprop -id $1 $2 " \
"| sed \"s/^$2(STRING) = //;s/^\\\"\\(.*\\)\\\"$/\\1/\" " \
"| sed -E 's/\\&/\\&/g; s/\\" "\"/\\"/g; s/</\\</g; s/>/\\>/g')\"" \
")\" && wname=\"$(xdotool getactivewindow getwindowname" \
")\" && echo \"<a href=\\" "\"$prop\\" "\">$wname</a>\" | tr -d '\\n' | xclip -selection c", \
"surf-setprop", winid, r, NULL \
} \
}
{ MODKEY, GDK_KEY_e, spawn, COPYLINK("_SURF_URI") },
config.h
:
#define COPYLINK() { \
.v = (const char *[]){ "/bin/sh", "-c", \
"xdotool key --clearmodifiers ctrl+y " \
"&& status=\"$(xclip -selection c -o " \
"| sed -E 's/\\&/\\&/g; s/\\" "\"/\\"/g; s/</\\</g; s/>/\\>/g'" \
")\" && wname=\"$(xdotool getactivewindow getwindowname" \
")\" && echo \"<a href=\\" "\"$status\\" "\">$wname</a>\" | tr -d '\\n' | xclip -selection c", \
NULL \
} \
}
{ MODKEY, GDK_KEY_e, spawn, COPYLINK() },
href
屬性値はステータステキストに依存
'
)のエスケープを削除
'
)のエスケープを削除
config.h
:
/* 選択した文字列をコピー */
/* COPYSEL() */
#define COPYSEL() { \
.v = (const char *[]){ "/bin/sh", "-c", \
"xdotool key --clearmodifiers ctrl+Insert", \
NULL \
} \
}
{ MODKEY, GDK_KEY_c, spawn, COPYSEL() },
xclip -selection p -o | xclip -selection c
でも良いかも
config.h
:
#define DOWNLOAD(u, r) { \
.v = (const char *[]){ "st", "-e", "/bin/sh", "-c", \
"wget \"$2\" " \
"&& echo \"DL 完了\" | dzen2 -p 4 -y 30 -bg '#008877' -fg '#ffffff'", \
"surf-download", r, u, NULL \
} \
}
wget
は ~/.wgetrc
で設定濟
'
)のエスケープを削除
surf-status.sh
:
#!/usr/bin/bash
# surf のアドレス・ステータステキストの通知
surf_prop=""_SURF_URI""
ellipsis="..."
# $ellipsis の分を入れて計算; [ $uri_maxstr = $(($uri_headstr + $uri_tailstr + $(echo $ellipsis | tr -d '\n' | wc -m))) ]
uri_maxstr="$((111 - 1))" # 前方の余白のため、1 引く
uri_headstr=56
uri_tailstr=51
# $ellipsis の分を入れて計算; [ $status_maxstr = $(($status_headstr + $status_tailstr + $(echo $ellipsis | tr -d '\n' | wc -m))) ]
status_maxstr=79
status_headstr=40
status_tailstr=36
bar_bg="#000000"
bar_fg_uri="#909090"
bar_fg_status="#60b0c0"
bar_font="monospace-14"
bar_h=26
bar_y="-$bar_h"
bar_w_status=800
bar_time=2
while true; do
wid_surf="$(xdotool search --class surf)"
wid="$(xdotool getactivewindow)"
if [ "$wid_surf" ] && [ "$wid" ] && [[ $(echo "$wid_surf" | grep -E $wid) ]]; then
# window bar: dzen2 -h 24
# top bar: dzen2 -y 24 -h 26
# URI
prop="$(printf '%b' "$(xprop -id $wid $surf_prop | sed "s/^$surf_prop(STRING) = //;s/^\"\(.*\)\"$/\1/")")"
if [[ $(echo "$prop" | grep -E ".{$uri_maxstr,}") ]]; then
prop="$(echo "$prop" | sed -E "s/^(.{$uri_headstr}).*(.{$uri_tailstr})$/\1$ellipsis\2/g")"
fi
echo "$prop " | dzen2 -ta r -p $bar_time -y $bar_y -h $bar_h -bg "$bar_bg" -fg "$bar_fg_uri" -fn "$bar_font" & # 黒, 右寄せ, 最下部
# STATUS
wname_surf="$(xdotool getwindowname $wid)"
if [[ $(echo "$wname_surf" | grep -E '^(.+://|mailto:)') ]]; then
if [[ $(echo "$wname_surf" | grep -E ".{$status_maxstr,}") ]]; then
wname_surf="$(echo "$wname_surf" | sed -E "s/^(.{$status_headstr}).*(.{$status_tailstr})$/\1$ellipsis\2/g")"
fi
# echo " $wname_surf" | dzen2 -ta l -p $bar_time -y -56 -x -600 -h 30 -w 600 -bg '#301000' -fg '#b09060' -fn "$bar_font" & # 赤, 右下, URI バーの上
echo " $wname_surf" | dzen2 -ta l -p $bar_time -y $bar_y -h $bar_h -w $bar_w_status -bg "$bar_bg" -fg "$bar_fg_status" -fn "$bar_font" & # 青, 左寄せ, URI バーに重ねる
fi
fi
sleep 1
done
dzen2
による通知を常時表示する(ループ)といふスクリプト
^.+://
)で始まる場合に通知を表示する
sleep
)を短くするとxdotool
がエラーを出すX Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 15 (X_QueryTree)
Resource id in failed request: 0x2a00005
Serial number of failed request: 429
Current serial number in output stream: 429
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 15 (X_QueryTree)
Resource id in failed request: 0x2a00005
Serial number of failed request: 429
Current serial number in output stream: 429
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 3 (X_GetWindowAttributes)
Resource id in failed request: 0x3800005
Serial number of failed request: 256
Current serial number in output stream: 257
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 15 (X_QueryTree)
Resource id in failed request: 0x2a00005
Serial number of failed request: 432
Current serial number in output stream: 432
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 15 (X_QueryTree)
Resource id in failed request: 0x2a00005
Serial number of failed request: 437
Current serial number in output stream: 437
XGetWindowProperty[_NET_ACTIVE_WINDOW] failed (code=1)
xdo_get_active_window reported an error
XGetWindowProperty[_NET_ACTIVE_WINDOW] failed (code=1)
xdo_get_active_window reported an error
[ "$wid_surf" ] && [ "$wid" ] &&
:存在確認は大事
xdotool
を起動)するつてできないかな?
default.css
:
/* surf のステータス通知用 */
html::after
{content: "" !important;
display: block !important;
height: 26px !important;}
html
{height: auto !important;}
html{height: auto !important;}
を追加
html,body{height: auto !important;}
surf-status-bkm.sh
:
#!/usr/bin/bash
# surf のアドレス・ステータステキストの通知(ブクマチェック附)
surf_prop=""_SURF_URI""
bkm_file="$HOME/.surf/bookmarks.htm"
ellipsis="..."
mark="★"
uri_maxstr="$((111 - 1))"
uri_headstr=56
uri_headstr_mark=54
uri_tailstr=51
status_maxstr=79
status_headstr=40
status_tailstr=36
bar_bg="#000000"
bar_fg_uri="#909090"
bar_fg_status="#60b0c0"
bar_font="monospace-14"
bar_h=26
bar_y="-$bar_h"
bar_w_status=800
bar_time=2
while true; do
wid_surf="$(xdotool search --class surf)"
wid="$(xdotool getactivewindow)"
if [ "$wid_surf" ] && [ "$wid" ] && [[ $(echo "$wid_surf" | grep -E $wid) ]]; then
# URI
prop="$(printf '%b' "$(xprop -id $wid $surf_prop | sed "s/^$surf_prop(STRING) = //;s/^\"\(.*\)\"$/\1/")")"
if [ -e $bkm_file ]; then # ブクマが存在するか
uri_anchor="$(echo "$prop" | sed -E 's/\&/\&/g; s/\"/\"/g; s/</\</g; s/>/\>/g')"
dup_num="$(grep -n "^<li><a href=\"$uri_anchor\">.*</a>$" $bkm_file)"
if [ "$dup_num" ]; then # 既存ブクマを確認
if [[ $(echo "$prop" | grep -E ".{$uri_maxstr,}") ]]; then
prop="$(echo "$prop" | sed -E "s/^(.{$uri_headstr_mark}).*(.{$uri_tailstr})$/\1$ellipsis\2$mark/g")"
else
prop="$(echo "$prop" | sed -E "s/^(.+)$/\1$mark/g")"
fi
else
if [[ $(echo "$prop" | grep -E ".{$uri_maxstr,}") ]]; then
prop="$(echo "$prop" | sed -E "s/^(.{$uri_headstr}).*(.{$uri_tailstr})$/\1$ellipsis\2/g")"
fi
fi
else
if [[ $(echo "$prop" | grep -E ".{$uri_maxstr,}") ]]; then
prop="$(echo "$prop" | sed -E "s/^(.{$uri_headstr}).*(.{$uri_tailstr})$/\1$ellipsis\2/g")"
fi
fi
echo "$prop " | dzen2 -ta r -p $bar_time -y $bar_y -h $bar_h -bg "$bar_bg" -fg "$bar_fg_uri" -fn "$bar_font" &
# STATUS
wname_surf="$(xdotool getwindowname $wid)"
if [[ $(echo "$wname_surf" | grep -E '^(.+://|mailto:)') ]]; then
if [[ $(echo "$wname_surf" | grep -E ".{$status_maxstr,}") ]]; then
wname_surf="$(echo "$wname_surf" | sed -E "s/^(.{$status_headstr}).*(.{$status_tailstr})$/\1$ellipsis\2/g")"
fi
echo " $wname_surf" | dzen2 -ta l -p $bar_time -y $bar_y -h $bar_h -w $bar_w_status -bg "$bar_bg" -fg "$bar_fg_status" -fn "$bar_font" &
fi
fi
sleep 1
done
surf-status.sh
に多少改訂を加へただけ
config.h
:
/* ブクマを追加 */
/* BKM() */
#define BKM() { \
.v = (const char *[]){ "/bin/sh", "-c", \
"bash ~/.surf/bookmark.sh", \
NULL \
} \
}
{ MODKEY, GDK_KEY_m, spawn, BKM() },
~/.surf/bookmark.sh
:
#!/usr/bin/bash
# surf からブックマークを追加
surf_prop=""_SURF_URI""
bkm_file="$HOME/.surf/bookmarks.htm"
bkm_minline=4
bkm_appendline=3
bkm_line="$(grep -cE '.' $bkm_file)"
myterm="st"
myeditor="kak"
notify_time=2
notify_y=30
notify_bg_delete="#603000"
notify_fg_delete="#f0f0f0"
notify_bg_warn="#500000"
notify_fg_warn="$notify_fg_delete"
if [ -e $bkm_file ] && [ -w $bkm_file ] && [ $bkm_line -ge $bkm_minline ]; then # ブクマが存在するか、書込めるか、(ソースが)最小行あるか
wid="$(xdotool getactivewindow)"
prop="$(printf '%b' "$(xprop -id $wid $surf_prop | sed "s/^$surf_prop(STRING) = //;s/^\"\(.*\)\"$/\1/" | sed -E 's/\&/\&/g; s/\"/\"/g; s/</\</g; s/>/\>/g')")"
dup_num="$(grep -n "^<li><a href=\"$prop\">.*</a>$" $bkm_file)"
if [ "$dup_num" ]; then # 既存ブクマを確認
dup_num="$(echo "$dup_num" | head -n 1 | sed -E 's/^([0-9]+):?.*$/\1/g')"
$myterm -e $myeditor $bkm_file +$dup_num # 既存ブクマの行をエディタで開く; 自動削除する場合は、この行を削除して以下をアンコメント
# sed -i ""$dup_num"d" $bkm_file # 既存ブクマを削除
# echo "ブクマを削除" | dzen2 -p $notify_time -y $notify_y -bg "$notify_bg_delete" -fg "$notify_fg_delete"
else
wname="$(xdotool getwindowname $wid)"
anchor="<li><a href=\"$prop\">$wname</a>"
sed -i -E ""$bkm_appendline"a$anchor" $bkm_file # 指定行へブクマを追加
echo "ブクマへ追加" | dzen2 -p $notify_time -y $notify_y
fi
else
echo "ブクマファイルを確認して下さい" | dzen2 -p $notify_time -y $notify_y -bg "$notify_bg_warn" -fg "$notify_fg_warn"
fi
sed -E 's/\&/\&/g; s/\"/\"/g; s/</\</g; s/>/\>/g'
:HTML に書込むなら、文字參照の事は忘れてはならない
grep -n "^<li><a href=\"$prop\">.*</a>$" $bkm_file
:-n
オプションがポイント。-nE
だと變數を讀まないらしい
echo "$dup_num" | head -n 1 | sed -E 's/^([0-9]+):?.*$/\1/g'
:head -n 1
は、重複があつた時のフォールバック
$myterm -e $myeditor $bkm_file +$dup_num
:+$dup_num
から書かないのは、先にファイル名が指定されてゐれば $dup_num
が取得できなくてもファイルを開けるから
~/.surf/bookmarks.htm
:
<!doctype html>
<title>ブクマ</title>
<ol reversed>
</ol>
sed
で處理し易い)
config.h
:
/* ブクマを編輯 */
/* EDITBKM() */
#define EDITBKM() { \
.v = (const char *[]){ "/bin/sh", "-c", \
"bkm_file=\"$HOME/.surf/bookmarks.htm\" " \
"&& if [ -e \"$bkm_file\" ] && [ -w \"$bkm_file\" ]; then " \
"st -e kak \"$bkm_file\" " \
"& firejail --noprofile --hosts-file=\"$HOME/.blockhosts\" surf \"$bkm_file\"; else " \
"echo \"ブクマファイルを確認して下さい\" | dzen2 -p 2 -y 30 -bg '#500000' -fg '#f0f0f0'; fi", \
NULL \
} \
}
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_m, spawn, EDITBKM() },
config.h
:
/* ウィンドウを閉ぢる */
/* QUIT() */
#define QUIT() { \
.v = (const char *[]){ "/bin/sh", "-c", \
"i3-msg kill", \
NULL \
} \
}
{ MODKEY, GDK_KEY_q, spawn, QUIT() },
config.h
:
/* キャッシュを削除 */
/* DELCACHE() */
#define DELCACHE() { \
.v = (const char *[]){ "/bin/sh", "-c", \
"cache_dir=\"$HOME/.surf/cache\" " \
"&& wid=\"$(xdotool getactivewindow)\" " \
"&& understanding=\"yes\" " \
"&& answer=\"$(echo \"$understanding\" | dmenu -w \"$wid\" -p \"キャッシュを削除しますか?\" -fn \"monospace-18\")\" " \
"&& [ \"$answer\" = \"$understanding\" ] " \
"&& find \"$cache_dir\" -mindepth 1 -exec rm -rf {} \\;", \
NULL \
} \
}
{ MODKEY, GDK_KEY_d, spawn, DELCACHE() },
at
などで計劃的・自動的に削除しても良い