📄 stlfilt.pl
字号:
s/\Q$keyclause//;
}
}
# Done with "with"-clause substitutions
#############################################################################################
# throw away those obnoxious C4786 warnings, and subsequent references to them
# (eliminates the need for unreliable #pragma hacking):
if (/C4786/ or /truncated to 255/)
{
$long_id = 1; # on long identifier warnings, set flag and cycle
next;
}
if ($long_id == 1)
{
/see reference to class template/ and next; # one kind of message referring to the warnings
/^ while/ and next; # VC spews sentence fragments relating to those warnings
}
$long_id = 0; # hopefully we've now caught all the crud that followed the long identifier warning...
# eliminate some noise:
s/\bstd\:\://g unless $keep_stdns;
s/\bstdext\:\://g unless $keep_stdns; # new VC 7.1 namespace
# The following section strips out the "class" keyword when it is part
# of a type name, but not when it is part of the 'prose' of a message.
# To do this, we only strip the word "class" when it follows an
# odd-numbered single quote (1st, 3rd, 5th, etc.):
$out = ""; # accumulate result into $out
$old = $_;
while (1)
{
if (($pos = index ($old, "'")) == -1) # index of next opening quote
{ # if none,
$out .= $old; # we're done
last;
}
$out .= substr($old, 0, $pos + 1, ""); # splice up to & including the "'" to $out
$pos = index($old, "'"); # index of next closing quote in $out
$txt = substr($old, 0, $pos + 1, ""); # splice from $old into $txt
$txt =~ s/\bclass //g if !/\btypedef\b/; # filter out "class" from $txt
$out .= $txt; # concatenate result to cumulative result
} # loop for next fragment
$_ = $out; # done; update entire current line
s/\bstruct ([^'])/$1/g if !/\btypedef\b/; # strip word "struct" (except for unnamed
# structs and typedefs)
s/\b__thiscall //g; # other stuff to strip...
s/\(__cdecl \*\)//g;
s/\b__cdecl\W//g;
s/\b_STLD?\:\://g unless $keep_stdns; # (for STLPort)
# simplify the ubiquitous "vanilla" string and i/ostreams (w/optional default allocator):
s/\b_?basic_(string|if?stream|of?stream|([io]?stringstream))<(char|wchar_t),char_traits<\3>(,_?allocator<\3>)? ?>/$1/g;
s/\b_?basic_(string|istream|ostream)<unsigned short,char_traits<unsigned short>(,_?allocator<unsigned short>)? ?>/w$1/g;
s/\b_?basic_(string|istream|ostream)<_(E(lem)?|CharT),_Tr(aits)?,_A(lloc)?>/$1/g;
s/\b([io])stream_iterator<($t),(?:__stl_)?char,char_traits<char> *(,$t)?>/$1stream_iterator<$2>/g;
# Dinkum Unabridged string iterators:
s/\b_String_iterator<char,char_traits<char>(,(allocator<char>|string::_Alloc))? ?>::_String_iterator\(/string::iterator(/g;
s/\b_String_iterator<char,char_traits<char>(,(allocator<char>|string::_Alloc))? ?>/string::iterator/g;
s/\b_String_const_iterator<char,char_traits<char>(,(allocator<char>|string::_Alloc))? ?>/string::const_iterator/g;
s/\b_String_iterator<(unsigned short|wchar_t),char_traits<(unsigned short|wchar_t)>(,(allocator<(unsigned short|wchar_t)>|string::_Alloc))? ?>::_String_iterator\(/wstring::iterator(/g;
s/\b_String_iterator<(unsigned short|wchar_t),char_traits<(unsigned short|wchar_t)>(,(allocator<(unsigned short|wchar_t)>|string::_Alloc))? ?>/wstring::iterator/g;
s/\b_String_const_iterator<(unsigned short|wchar_t),char_traits<(unsigned short|wchar_t)>(,(allocator<(unsigned short|wchar_t)>|string::_Alloc))? ?>/wstring::const_iterator/g;
# The following loop repeats until no transformations occur in the last complete iteration:
for ($pass = 1; ;$pass++) # pass count (for de-bugging purposes only)
{
my $before = $_; # save the current line; keep looping while changes happen
# Handle allocator clauses:
# Unless .NET with 'L' allocator policy, delete allocators from template typenames completely:
unless ($dotNET == 1 and $alloc_policy eq 'L')
{
s/,? ?allocator<$t ?> ?>/>/g;
s/,? ?allocator<$t ?>(,(0|1|true|false)) ?>/$1>/g;
}
if ($dotNET == 1 and $func_policy eq 'S')
{
s/,? ?hash_compare<$t ?> ?>/>/g;
s/,? ?equal<$t ?> ?>/>/g;
}
# remove allocator/hash_compare/equal parameters completely if this is not .NET
# *AND* the message doesn't refer to the parameter explicitly:
unless ($dotNET == 1 or /' to '.*allocator</)
{
s/,allocator<$t ?> ?//g; # the leading comma allows the full spec.
s/,const allocator<$t ?> ?&//g; # to appear in the error message details
}
unless ($dotNET == 1 or /' to '.*hash_compare</) # same for hash_compare
{
s/,hash_compare<$t ?> ?//g;
s/,const hash_compare<$t ?> ?&//g;
}
unless ($dotNET == 1 or /' to '.*equal</) # same for equal
{
s/,equal<$t ?> ?//g;
s/,const equal<$t ?> ?&//g;
}
# unless .NET with 'L' allocator policy, reduce any remaining allocator parameters to just "$alloc":
unless (($dotNET == 1 and $alloc_policy eq 'L') or ($dotNET == 0 and / to '.*allocator</))
{
s/\ballocator<$t ?> ?([\)'])/$alloc$1/g;
s/\b$t\:\:_Alloc/$alloc/g;
s/\b$t\:\:allocator_type/$alloc/g;
s/\bconst allocator<$t ?> &([\)'])/const $alloc$1/g;
}
# STLPort vector iterators:
s/\breverse_iterator<($t) \*,\1,\1 &,\1 \*,$t>/vector<$1>::reverse_iterator/g;
s/\breverse_iterator<($t) const \*,\1,\1 const &,\1 const \*,$t>/vector<$1>::const_reverse_iterator/g;
# STLPort vector iterators under VC7:
s/\breverse_iterator<vector<($t)>\:\:iterator,vector<\1>\:\:value_type,vector<\1>\:\:reference,\1 \*,vector<\1>\:\:difference_type>/vector<$1>::reverse_iterator/g;
s/\breverse_iterator<vector<($t)>\:\:const_iterator,vector<\1>\:\:value_type,vector<\1>\:\:const_reference,\1 const \*,vector<\1>\:\:difference_type>/vector<$1>::const_reverse_iterator/g;
# STLPort deque iterators under VC7:
s/\bdeque<($t)>\:\:iterator,deque<\1>\:\:value_type,deque<\1>\:\:reference,deque<\1>\:\:pointer,deque<\1>\:\:difference_type/deque<$1>::iterator/g;
s/\bdeque<($t)>\:\:const_iterator,deque<\1>\:\:value_type,deque<\1>\:\:const_reference,deque<\1>\:\:const_pointer,deque<\1>\:\:difference_type/deque<$1>::const_iterator/g;
# STLPort list and deque iterators:
s/\b_(Sl|L)ist_iterator<($t),_Nonconst_traits<\2 ?> ?>\:\:_\1ist_iterator\(/\l$1ist<$2>::iterator(/g;
s/\b_(Sl|L)ist_iterator<($t),_Const_traits<\2 ?> ?>\:\:_\1ist_iterator\(/\l$1ist<$2>::const_iterator(/g;
s/\b_Deque_iterator<($t),_Nonconst_traits<\1 ?> ?>\:\:_Deque_iterator\(/deque<$1>::iterator(/g;
s/\b_Deque_iterator<($t),_Const_traits<\1 ?> ?>\:\:_Deque_iterator\(/deque<$1>::const_iterator(/g;
s/\b_(Sl|L)ist_iterator<($t),_Nonconst_traits<\2 ?> ?>/\l$1ist<$2>::iterator/g;
s/\b_(Sl|L)ist_iterator<($t),_Const_traits<\2 ?> ?>/\l$1ist<$2>::const_iterator/g;
s/\b_Deque_iterator<($t),_Nonconst_traits<\1 ?> ?>/deque<$1>::iterator/g;
s/\b_Deque_iterator<($t),_Const_traits<\1 ?> ?>/deque<$1>::const_iterator/g;
# more STLPort list iterators
s/\blist<($t)>\:\:iterator,list<\1>\:\:value_type,list<\1>\:\:reference,list<\1>\:\:pointer,list<\1>\:\:difference_type/list<$1>::iterator/g;
s/\blist<($t)>\:\:const_iterator,list<\1>\:\:value_type,list<\1>\:\:const_reference,list<\1>\:\:const_pointer,list<\1>\:\:difference_type/list<$1>::const_iterator/g;
s/\b_List_node<($t) ?> ?\*/list<$1>::iterator/g;
# STLPort hash_set/_multiset iterators:
s/\b_Ht_iterator<($t),_Const_traits<\1 ?> ?(,\1) ?,$id<\1>,$id<\1>,$id<\1> ?>/gen_hash_set<$1>::const_iterator/g;
s/\b_Ht_iterator<($t),_Nonconst_traits<\1 ?> ?(,\1) ?,$id<\1> ?,$id<\1> ?,$id<\1> ?>/gen_hash_set<$1>::iterator/g;
# STLPort hash_set/_multiset iterators under VC7:
s/\b_Ht_iterator<($t),hashtable<\1,\1,hash<\1>,_Identity<\1>,equal_to<\1> ?>\:\:__const_val_traits,\1,hash<\1>,_Identity<\1>,equal_to<\1> ?>\:\:_Ht_iterator\(/gen_hash_set<$1>::const_iterator(/g;
s/\b_Ht_iterator<($t),hashtable<\1,\1,hash<\1>,_Identity<\1>,equal_to<\1> ?>\:\:__nonconst_val_traits,\1,hash<\1>,_Identity<\1>,equal_to<\1> ?>\:\:_Ht_iterator\(/gen_hash_set<$1>::iterator(/g;
s/\b_Ht_iterator<($t),hashtable<\1,\1,hash<\1>,_Identity<\1>,equal_to<\1> ?>\:\:__const_val_traits,\1,hash<\1>,_Identity<\1>,equal_to<\1> ?>/gen_hash_set<$1>::const_iterator/g;
s/\b_Ht_iterator<($t),hashtable<\1,\1,hash<\1>,_Identity<\1>,equal_to<\1> ?>\:\:__nonconst_val_traits,\1,hash<\1>,_Identity<\1>,equal_to<\1> ?>/gen_hash_set<$1>::iterator/g;
# STLPort hash_set/_multiset:
s/\b(hash_(?:multi)?)set<($t)(,hash<\2 ?>)? ?(,equal_to<\2 ?>)? ?>/$1set<$2>/g;
# STLPort map/multimap iterators ("GENERIC" iterator approach; see below):
s/\b_Rb_tree_iterator<pair<($t) const ?,($t)>,_Nonconst_traits<pair<\1 const ?,\2> ?> ?>/gen_map<$1,$2>::iterator/g;
s/\b_Rb_tree_iterator<pair<($t) const ?,($t)>,_Const_traits<pair<\1 const ?,\2> ?> ?>/gen_map<$1,$2>::const_iterator/g;
s/\b_Rb_tree_node<pair<($t) const ?,($t) ?> ?> ?\*/gen_map<$1,$2>::const_iterator/g; # they're all const
# STLPort map/multimap under VC7:
s/\b_Rb_tree<((?:multi)?map)<($t),($t)(?:,$t)?>\:\:key_type,\2,_Select1st<\2>,\1<\2,\3(,$t)?>\:\:key_compare>/$1<$2,$3>/g;
s/\b_Rb_tree<((?:multi)?map)<($t),($t)(?:,$t)?>\:\:key_type,(pair<\2,\3>),_Select1st<\4>,\1<\2,\3(,$t)?>\:\:key_compare>/$1<$2,$3>/g;
s/\bmap<($t,$t)>\:\:const_iterator,pair<\1>,map<\1>\:\:const_reference,map<\1>\:\:const_pointer,map<\1>\:\:difference_type>/map<$1>::iterator/g;
# STLPort set/multiset under VC7:
s/\b_Rb_tree<set<($t)>\:\:key_type,\1, ?_Identity<\1>,set<\1>\:\:key_compare>/set<$1>/g;
s/\bset<($t)>\:\:const_iterator,\1,set<\1>\:\:const_reference,set<\1>\:\:const_pointer,set<\1>\:\:difference_type>/set<$1>::const_iterator/g;
# STLPort map/multimap iterators under VC7 ("GENERIC" iterator approach; see below):
s/\b_Rb_tree_iterator<pair<($t),($t)>,_Nonconst_traits<pair<\1,\2> ?> ?>\:\:_Rb_tree_iterator\(/gen_map<$1,$2>::iterator(/g;
s/\b_Rb_tree_iterator<pair<($t),($t)>,_Const_traits<pair<\1,\2> ?> ?>\:\:_Rb_tree_iterator\(/gen_map<$1,$2>::const_iterator(/g;
s/\b_Rb_tree_iterator<pair<($t),($t)>,_Nonconst_traits<pair<\1,\2> ?> ?>/gen_map<$1,$2>::iterator/g;
s/\b_Rb_tree_iterator<pair<($t),($t)>,_Const_traits<pair<\1,\2> ?> ?>/gen_map<$1,$2>::const_iterator/g;
# STLPort hash_map/_multimap iterators ("GENERIC" iterator approach; see below):
s/\b_Ht_iterator<pair<($t) const ?,($t)>,_Nonconst_traits<pair<\1 const ?,\2> ?>,\1,hash<\1 ?>,_Select1st<pair<\1 const ?,\2> ?>,equal_to<\1 ?> ?>\:\:_Ht_iterator\(/gen_hash_map<$1,$2>::iterator(/g;
s/\b_Ht_iterator<pair<($t) const ?,($t)>,_Const_traits<pair<\1 const ?,\2> ?>,\1,hash<\1 ?>,_Select1st<pair<\1 const ?,\2> ?>,equal_to<\1 ?> ?>\:\:_Ht_iterator\(/gen_hash_map<$1,$2>::const_iterator(/g;
s/\b_Ht_iterator<pair<($t) const ?,($t)>,_Nonconst_traits<pair<\1 const ?,\2> ?>,\1,hash<\1 ?>,_Select1st<pair<\1 const ?,\2> ?>,equal_to<\1 ?> ?>/gen_hash_map<$1,$2>::iterator/g;
s/\b_Ht_iterator<pair<($t) const ?,($t)>,_Const_traits<pair<\1 const ?,\2> ?>,\1,hash<\1 ?>,_Select1st<pair<\1 const ?,\2> ?>,equal_to<\1 ?> ?>/gen_hash_map<$1,$2>::const_iterator/g;
# STLPort hash_map/_multimap iterators under VC7 (same "GENERIC" iterator approach as described below):
s/\b_Ht_iterator<pair<const ($t),($t)>,hash_map<\1,\2>\:\:__nonconst_val_traits,\1,hash<\1 ?>,_Select1st<pair<const \1,\2> ?>,equal_to<\1 ?> ?>\:\:_Ht_iterator\(/gen_hash_map<$1,$2>::iterator(/g;
s/\b_Ht_iterator<pair<const ($t),($t)>,hash_map<\1,\2>\:\:__const_val_traits,\1,hash<\1 ?>,_Select1st<pair<const \1,\2> ?>,equal_to<\1 ?> ?>\:\:_Ht_iterator\(/gen_hash_map<$1,$2>::const_iterator(/g;
s/\b_Ht_iterator<pair<const ($t),($t)>,hash_map<\1,\2>\:\:__nonconst_val_traits,\1,hash<\1 ?>,_Select1st<pair<const \1,\2> ?>,equal_to<\1 ?> ?>/gen_hash_map<$1,$2>::iterator/g;
s/\b_Ht_iterator<pair<const ($t),($t)>,hash_map<\1,\2>\:\:__const_val_traits,\1,hash<\1 ?>,_Select1st<pair<const \1,\2> ?>,equal_to<\1 ?> ?>/gen_hash_map<$1,$2>::const_iterator/g;
# STLPort hash_map/_multimap:
s/\b(hash_(?:multi)?)map<($t),($t)(,hash_compare(<\2 ?>)?)? ?(,$t(<\2 ?>)?)? ?>/$1map<$2,$3>/g;
s/\b(hash_(?:multi)?)map<($t),($t)(,equal(<\2 ?>)?)? ?>/$1map<$2,$3>/g;
# STLPort hash_map/_multimap under VC7:
s/\bhashtable<pair<const ($t),($t)>,\1,hash<\1>,_Select1st<pair<const \1,\2> ?>,$t<\1> ?>/hash_map<$1,$2>/g;
# STLPort set/multiset iterators ("GENERIC" iterator approach):
# Since STLPort uses the same iterator type for both set and multiset, we just
# say "gen_set<T>::iterator" to mean the "GENERIC" set/multiset iterator type:
s/\b_Rb_tree_iterator<($t),_Nonconst_traits<\1 ?> ?>/gen_set<$1>::iterator/g;
s/\b_Rb_tree_iterator<($t),_Const_traits<\1 ?> ?>/gen_set<$1>::const_iterator/g;
s/\b((const_)?iterator)\:\:_Rb_tree_iterator\(/$1(/g;
s/\b_Rb_tree_iterator<(_Rb_tree<set<($t)(?:,($t)<\2>)?>\:\:key_type,set<\2(?:,\3<\2>)?>\:\:value_type,_Identity<set<\2(?:,\3<\2>)?>\:\:value_type>,set<\2(,\3<\2>)?>\:\:key_compare>\:\:value_type),_Const_traits<\1> ?>/gen_set<$2>::const_iterator/g;
s/\b_Rb_tree_iterator<(_Rb_tree<set<($t)(?:,($t)<\2>)?>\:\:key_type,set<\2(?:,\3<\2>)?>\:\:value_type,_Identity<set<\2(?:,\3<\2>)?>\:\:value_type>,set<\2(,\3<\2>)?>\:\:key_compare>\:\:value_type),_Nonconst_traits<\1> ?>/gen_set<$2>::iterator/g;
s/\b_Rb_tree_iterator<_Rb_tree<set<($t)>\:\:key_type,\1,_Identity<\1>,set<\1>\:\:key_compare>\:\:value_type,_Const_traits<\1> ?>/gen_set<$1>::const_iterator/g;
s/\b_Rb_tree_iterator<_Rb_tree<set<($t)>\:\:key_type,\1,_Identity<\1>,set<\1>\:\:key_compare>\:\:value_type,_Nonconst_traits<\1> ?>/gen_set<$1>::iterator/g;
s/\b_Rb_tree_node<($t) ?> ?\*/gen_set<$1>::const_iterator/g; # they're all const
# STLPort de-bug iterator: reduce the entire thing to just "dbg_iter"
while (/\b_DBG_iter</)
{
$start = $pos = index ($_, "_DBG_iter<") + 10;
$depth = 1;
while ($depth)
{
$next = substr ($_, $pos++, 1);
$depth++ if $next eq "<";
$depth-- if $next eq ">";
}
$_ = substr($_, 0, $start - 1) . " " . substr($_, $pos);
}
s/\b_DBG_iter\b/dbg_iter/g;
# Dinkumware vector iterators:
s/\b_Ptrit<($t),$t,\1 const \*,\1 const &,\1 \*,\1 &>/vector<$1>::const_iterator/g;
s/\b_Ptrit<($t),$t,\1 \*,\1 &,\1 \*,\1 &>/vector<$1>::iterator/g;
# VC7 vector iterators:
s/\bvector<($t)>\:\:(_Tptr|pointer)\b/$1 */g;
s/\bvector<($t)>\:\:(_Ctptr|const_pointer)\b/$1 const */g;
s/\b_Ptrit<vector<($t)>\:\:value_type,vector<\1>\:\:difference_type,\1 \*,vector<\1>\:\:reference,\1 \*,vector<\1>\:\:reference>/vector<$1>::iterator/g;
s/\b_Ptrit<vector<($t)>\:\:value_type,vector<\1>\:\:difference_type,\1 const \*,vector<\1>\:\:const_reference,\1 \*,vector<\1>\:\:reference>/vector<$1>::const_iterator/g;
# Dinkum Unabridged Library vector/deque iterators:
s/\b_Vector_iterator<($t)(,($alloc|vector<\1>::_Alloc))?>::_Vector_iterator\(/vector<$1>::iterator(/g;
s/\b_Vector_const_iterator<($t)(,($alloc|vector<\1>::_Alloc))?>::_Vector_const_iterator\(/vector<$1>::const_iterator(/g;
s/\b_Vector_iterator<($t)(,($alloc|vector<\1>::_Alloc))?>/vector<$1>::iterator/g;
s/\b_Vector_const_iterator<($t)(,($alloc|vector<\1>::_Alloc))?>/vector<$1>::const_iterator/g;
s/\b_Deque_iterator<($t)(,($alloc|deque<\1>::_Alloc))?>::_Deque_iterator\(/deque<$1>::iterator(/g;
s/\b_Deque_const_iterator<($t)(,($alloc|deque<\1>::_Alloc))?>::_Deque_const_iterator\(/deque<$1>::const_iterator(/g;
s/\b_Deque_iterator<($t)(,($alloc|deque<\1>::_Alloc))?>/deque<$1>::iterator/g;
s/\b_Deque_const_iterator<($t)(,($alloc|deque<\1>::_Alloc))?>/deque<$1>::const_iterator/g;
# Dinkumware map/multimap:
s/\b((?:multi)?)map<($t),($t)((:?,$t(<\2 ?>)?)?) ?>/$1map<$2,$3$4>/g;
s/\b_Tree<_Tmap_traits<($t),($t)((:?,$t(<\1 ?>)?)?),(0|false) ?> ?>/map<$1,$2$3>/g;
s/\b_Tree<_Tmap_traits<($t),($t)((:?,$t(<\1 ?>)?)?),(1|true) ?> ?>/multimap<$1,$2$3>/g;
# Dinkumware hash_map/hash_multimap:
s/\b(hash_(?:multi)?)map<($t),($t)(,hash_compare(<\2 ?>)?)? ?(,$t(<\2 ?>)?)? ?>/$1map<$2,$3>/g;
s/\b(hash_(?:multi)?)map<($t),($t)(,equal(<\2 ?>)?)? ?>/$1map<$2,$3>/g;
s/\b(hash_(?:multi)?)map<($t),($t)((?:,$t(<\2 ?>)?)?) ?(,$t(<\2 ?>)?)? ?>/$1map<$2,$3$4>/g;
s/\b_Hash<_Hmap_traits<($t),($t)((?:,$t(<\1 ?>)?)?),(0|false) ?> ?>/hash_map<$1,$2$3>/g;
s/\b_Hash<_Hmap_traits<($t),($t)((?:,$t(<\1 ?>)?)?),(1|true) ?> ?>/hash_multimap<$1,$2$3>/g;
# native VC6 list iterators:
s/\blist<($t)>\:\:iterator,\1,\1 &,\1 \*,int/list<$1>::iterator/g;
s/\blist<($t)>\:\:const_iterator,\1,\1 const &,\1 const \*,int/list<$1>::const_iterator/g;
# native VC6 iterators:
s/\b($t)\:\:_Node \*/$1::iterator/g;
# native VC7 iterators:
s/\b($t)\:\:_Nodeptr/$1::iterator/g;
# Dinkum / VC7 reverse iterators:
s/\b_Revbidit<($t)\:\:iterator,\1\:\:iterator>/$1::reverse_iterator/g;
s/\b_Revbidit<($t)\:\:const_iterator,\1\:\:iterator>/$1::const_reverse_iterator/g;
# native VC6 map/multimap:
s/\bmap<($t),($t)>\:\:iterator,pair<\1 const ?,\2 ?>,pair<\1 ?,\2 ?> &,pair<\1 ?,\2 ?> \*,\1/map<$1,$2>::iterator/g;
s/\bmap<($t),($t)>\:\:const_iterator,(pair<\1 const ?,\2 ?>),\3 const &,\3 const \*,\1/map<$1,$2>::const_iterator/g;
s/\b_Tree<($t),pair<\1 const ?,($t) ?>,((?:multi)?map)<\1,\2(,$t(<\1 ?>)?)? ?>\:\:_Kfn\4? ?>/$3<$1,$2>/g;
s/\(const pair<($t) const ?,($t) ?> \*,const pair<\1 const ?,\2 ?> \*,const $t<\1 ?> & ?&\)/($newiter, $newiter, $3<$1>)/g;
# map/multimap members common to native/Dinkum:
s/\bpair<($t) const ?,($t) ?> ([\*&])/pair<$1,$2> $3/g;
# native VC6 set/multiset
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -