Android java: How to display phonetic symbol with correct fonts via WebView ?
First, Download lingoes font file
Android default fonts can not display phonetic symbol.lingoes.ttf can, please download it.
Second, Put lingoes.ttf to assets/font

Last, Add "lingoes" font-family in css files under assets
@font-face { font-family: 'lingoes'; src:url('file:///android_asset/fonts/lingoes.ttf') format('truetype'); font-weight: normal; font-style: normal; }
Use "lingoes" as font-family for the phonetic symbol content
Android java : How to load html files in assets via WebView?Android java : How to load html files in assets via WebView?
"file:///android_asset/"
WebView wv = new WebView(context); wv.getSettings().setJavaScriptEnabled(true); wv.loadUrl("file:///android_asset/coca/coca_00001_the.html");
Android java : How to copy/move file from assets to absolute path?
private void moveAssets(String assets_file_path, String absolutePath) throws IOException { File wwwFile = new File(absolutePath); if (wwwFile.exists()) return; InputStream is = activity.getAssets().open(assets_file_path); byte[] buffer = new byte[is.available()]; is.read(buffer); is.close(); wwwFile.createNewFile(); FileOutputStream os = new FileOutputStream(wwwFile); os.write(buffer); os.close(); }
Android java: How to orientation activity layout automatically ?
Add ~android:screenOrientation="fullSensor"~ to the activity
AndroidManifest.xml activity android:name=".MainActivity" android:screenOrientation="fullSensor"
shell bash scripts : check process existed or not, if not existed then restart it
It will auto run "unison" process if not running yet
when you open a new bash shell every time.
Change the process name "unison" for your case. :)
auto_unison() { u=`ps aux | grep unison | grep -v grep | wc -l` if [ $u -eq 0 ] then unison > /dev/null 2>&1 & fi } auto_unison
Android how to detect/register language/locale change listener/receiver
The easy way is to register a BroadcastReceiver for Intent.ACTION_LOCALE_CHANGED.
Example: change your ViewModel data when language/locale changed.
public class QASViewModel extends ViewModel { @SuppressLint("StaticFieldLeak") private final FragmentActivity activity; public QASViewModel(@NonNull FragmentActivity activity) { this.activity = activity; setLangReceiver(); } private void setLangReceiver() { final QASViewModel qasViewModel = this; final BroadcastReceiver langReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // do action when language change } }; activity.getApplicationContext().registerReceiver(langReceiver, new IntentFilter(Intent.ACTION_LOCALE_CHANGED)); } }
Android ViewModel with ArgsConstructor via Custom ViewModelFactory
Android ViewModel is very useful.
However ViewModel has no args constructor by default.
Typical usage of ViewModel looks like:
public class UserModel extends ViewModel { } final UserModel viewModel = ViewModelProviders.of(this).get(UserModel.class);
Let's look the definition of ViewModelProviders.of method.
/** * Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given Activity * is alive. More detailed explanation is in {@link ViewModel}. ** It uses the given {@link Factory} to instantiate new ViewModels. * * @param activity an activity, in whose scope ViewModels should be retained * @param factory a {@code Factory} to instantiate new ViewModels * @return a ViewModelProvider instance */ @NonNull @MainThread public static ViewModelProvider of(@NonNull FragmentActivity activity, @Nullable Factory factory) {
Have you found it? We can pass a Factory to create the ViewModel.
Implement your own Factory then you can have args constructor for your ViewModel.
Here we set up a ViewModel with 1 argument construcgtor.
Example code:
public QASViewModel(@NonNull FragmentActivity activity) { this.activity = activity; } QASViewModel qasViewModel = ViewModelProviders.of(getActivity(), new QASViewModelFactory(getActivity())).get(QASViewModel.class);
import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; import java.lang.reflect.InvocationTargetException; public class QASViewModelFactory extends ViewModelProvider.NewInstanceFactory { private final FragmentActivity activity; /** * Creates a {@code AndroidViewModelFactory} * * @param activity an AssetManager to pass in {@link QASViewModel} */ public QASViewModelFactory(@NonNull FragmentActivity activity) { this.activity = activity; } @NonNull @Override publicT create(@NonNull Class modelClass) { if (QASViewModel.class.isAssignableFrom(modelClass)) { try { return modelClass.getConstructor(FragmentActivity.class).newInstance(activity); } catch (NoSuchMethodException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } catch (IllegalAccessException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } catch (InstantiationException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } catch (InvocationTargetException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } } return super.create(modelClass); } }
How to convert UTC Date Time String to Java object and compare it ?
import java.time.Instant;
Instant instantStart = Instant.parse("20200229T12:00:00Z");
Instant instantEnd = Instant.parse("20200329T12:00:00Z");
Instant instantNow = Instant.now();
return instantNow.isAfter(instantStart) &&
instantNow.isBefore(instantEnd);
How to convert json array to java Object
import com.amazonaws.util.json.Jackson;
import java.util.ArrayList;
import lombok.Data;
@Data
class DeviceList {
private ArrayList<String> devices;
}
DeviceList deviceList = Jackson.fromJsonString(
"{\"devices\":[\"Mobile\", \"Desktop\"]}",
DeviceList.class);
Java Spring Bean constructor how to get call stack, backtrace
Implement a function and throw an Exception.
Call the function in the place you want to know its backtrace or callstack
And Catch the Exception then
Call Exception.getStackTrace
class MyService { public static void f() throws Exception { throw new Exception(); } void forTest() { try { f(); } catch (Exception e) { e.printStackTrace(); } } }
Via this solution, we can get Bean constructor call stack easily.
[tomcat:launchProperties] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[tomcat:launchProperties] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[tomcat:launchProperties] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[tomcat:launchProperties] at java.lang.reflect.Method.invoke(Method.java:498)
[tomcat:launchProperties] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
[tomcat:launchProperties] at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
[tomcat:launchProperties] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1178)
[tomcat:launchProperties] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1072)
[tomcat:launchProperties] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)
[tomcat:launchProperties] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)
[tomcat:launchProperties] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
[tomcat:launchProperties] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
[tomcat:launchProperties] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
[tomcat:launchProperties] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
[tomcat:launchProperties] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
[tomcat:launchProperties] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1136)
[tomcat:launchProperties] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
[tomcat:launchProperties] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:583)
[tomcat:launchProperties] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
[tomcat:launchProperties] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:364)
[tomcat:launchProperties] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1269)
[tomcat:launchProperties] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:551)
[tomcat:launchProperties] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)
[tomcat:launchProperties] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
[tomcat:launchProperties] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
[tomcat:launchProperties] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
[tomcat:launchProperties] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
[tomcat:launchProperties] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
[tomcat:launchProperties] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
[tomcat:launchProperties] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
[tomcat:launchProperties] at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443)
[tomcat:launchProperties] at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325)
[tomcat:launchProperties] at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
[tomcat:launchProperties] at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4851)
[tomcat:launchProperties] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5314)
[tomcat:launchProperties] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
[tomcat:launchProperties] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
[tomcat:launchProperties] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
[tomcat:launchProperties] at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[tomcat:launchProperties] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[tomcat:launchProperties] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[tomcat:launchProperties] at java.lang.Thread.run(Thread.java:748)
How to use @Mock @InjectMocks
class MyService { private UserDao userDao; } import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.runners.MockitoJUnitRunner; public class MyServiceTest { @InjectMocks private MyService myService; @Mock private UserDao userDao; @Before public void setUp() { myService = new MyService(); } }
Cannot mock/spy class java.lang.String Mockito cannot mock/spy following: - final classes - anonymous classes - primitive types org.mockito.exceptions.base.MockitoException: Cannot mock/spy class java.lang.String Mockito cannot mock/spy following: - final classes - anonymous classes - primitive types at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl$1.withBefores(JUnit45AndHigherRunnerImpl.java:27) at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
In case you have to mock String, perhaps you can add a function only visible for testing viaimport com.google.common.annotations.VisibleForTesting;
And in this function, mock the String type's value.
For Example:
class MyService {
private String name = "myservice";
@VisibleForTesting
void forTest(String mockName) {
this.name = mockName;
}
}
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;
public class MyServiceTest {
private MyService myService;
@Before
public void setUp() {
myService = new MyService();
myService.forTest("mockName");
}
}
How to increase terminal window buffer in IntelliJ
Command + Shift + A or Ctrl + Shift + A
Type registry, click "Registry..."
Increase the "terminal.buffer.max.lines.count" to 100000 or any number you want, the default is 1000.
make vim like source insight, a effective c/c++ ide
IDE
setup latest vim
git clone https://github.com/vim/vim.git cd vim/src ./configure --enable-cscope --enable-terminal make sudo make install
use universal ctags
git clone https://github.com/universal-ctags/ctags.git cd ctags ./autogen.sh ./configure make sudo make instahttps://www.tamacom.com/global/global-6.6.3.tar.gzll
setup gnu tags
wget https://www.tamacom.com/global/global-6.6.3.tar.gz tar -xvf global-6.6.3.tar.gz cd global-6.6.3 sh reconf.sh sudo apt install ncurses-dev ./configure --with-universal-ctags=/usr/local/bin/ctags make sudo make install
https://www.tamacom.com/global/global-6.6.3.tar.gz
http://www.gnu.org/software/global/download.html
install gtags as vim plugin
cp gtags.vim ~/.vim/plugin/ cp gtags-cscope.vim ~/.vim/plugin/
config gtags as cscope in ~/.vimrc
" gtags configure " To use the default key/mouse mapping: let GtagsCscope_Auto_Map = 1 " To ignore letter case when searching: let GtagsCscope_Ignore_Case = 1 " To use absolute path name: let GtagsCscope_Absolute_Path = 1 " To deterring interruption: let GtagsCscope_Keep_Alive = 1 " If you hope auto loading: let GtagsCscope_Auto_Load = 1 let GtagsCscope_Quiet = 1 " To use 'vim -t ', ':tag' and '<C-]>' set cscopetag let Gtags_Auto_Map = 1 " output cscope result to quickfix set cscopequickfix=s-,g-,c-,d-,i-,t-,e-,f-,-a " open quickfix window if needx autocmd QuickFixCmdPost [^l]* nested botright cwindow :nmap \s :cs find s <C-R>=expand("<cword>")<CR><CR> :nmap \a :cs find a <C-R>=expand("<cword>")<CR><CR> :nmap \d :cs find d <C-R>=expand("<cword>")<CR><CR> :nmap \g :cs find g <C-R>=expand("<cword>")<CR><CR> :nmap \i :cs find i <C-R>=expand("<cword>")<CR><CR> :nmap \c :cs find c <C-R>=expand("<cword>")<CR><CR> :nmap \e :cs find e <C-R>=expand("<cword>")<CR><CR> :nmap \t :cs find t <C-R>=expand("<cword>")<CR><CR> :nmap \f :cs find f <C-R>=expand("<cword>")<CR><CR>
Usage:
cscope commands: add : Add a new database (Usage: add file|dir [pre-path] [flags]) find : Query for a pattern (Usage: find a|c|d|e|f|g|i|s|t name) a: Find assignments to this symbol c: Find functions calling this function d: Find functions called by this function e: Find this egrep pattern f: Find this file g: Find this definition i: Find files #including this file s: Find this C symbol t: Find this text string help : Show this message (Usage: help) kill : Kill a connection (Usage: kill #) reset: Reinit all connections (Usage: reset) show : Show connections (Usage: show)
Normal Key Map:
Press \a means "cs f a $cname"
Press \s means "cs f s $cname"
Press \t means "cs f t $cname"
Press \e means "cs f e $cname"
Press \c means "cs f c $cname"
Press \d means "cs f d $cname"
Press \i means "cs f i $cname"
Press \g means "cs f g $cname"
Press \f means "cs f f $cname"
install taglist
unzip taglist_46.zip Archive: taglist_46.zip inflating: plugin/taglist.vim inflating: doc/taglist.txt cp plugin/taglist.vim ~/.vim/plugin/ cp doc/taglist.txt ~/.vim/doc/
https://www.vim.org/scripts/script.php?script_id=273
configure taglist vim plugin
"taglist settings let Tlist_Inc_Winwidth=0 let Tlist_Use_Right_Window=1 let Tlist_File_Fold_Auto_Close=1 let Tlist_Exit_OnlyWindow=1 let Tlist_Auto_Open=1 :nmap <F8> :TlistToggle<CR> function! g:TlistFocus() let save_winnr = winnr() let winnum = bufwinnr("__Tag_List__") if winnum == -1 :TlistToggle let winnum = bufwinnr("__Tag_List__") endif if winnum != -1 if save_winnr != winnum exe winnum . 'wincmd w' endif endif endfunction "focus to Tag list window via CTL command command! -nargs=0 -bar CTL call g:TlistFocus()
Usage: Press F8 to toggle taglist
install vim-airline
git clone https://github.com/vim-airline/vim-airline ~/.vim/pack/dist/start/vim-airline
https://github.com/vim-airline/vim-airline
install fzf.vim
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf ~/.fzf/install
~/.vimrc
" If installed using git set rtp+=~/.fzf
.vimrc
set nocompatible set backspace=indent,eol,start syntax on syntax enable filetype plugin indent on set autoread set showmatch set hlsearch set incsearch set ignorecase set smartcase set encoding=utf-8 set termencoding=utf-8 set fileencodings=utf-8,gb2312,gbk,gb18030 set tabstop=4 set shiftwidth=4 set expandtab set softtabstop=4 set autoindent set smartindent set ruler set paste "gtags settings set cscopetag let GtagsCscope_Auto_Load = 1 let CtagsCscope_Auto_Map = 1 let GtagsCscope_Quiet = 1 set cscopequickfix=s-,g-,d-,c-,t-,e-,f-,i- "open quickfix window if needed autocmd QuickFixCmdPost [^l]* nested botright cwindow "key maps for gtags "find : Query for a pattern (Usage: find a|c|d|e|f|g|i|s|t name) " a: Find assignments to this symbol " c: Find functions calling this function " d: Find functions called by this function " e: Find this egrep pattern " f: Find this file " g: Find this definition " i: Find files #including this file " s: Find this C symbol " t: Find this text string :nmap \a :cs find a <C-R>=expand("<cword>")<CR><CR> :nmap \c :cs find c <C-R>=expand("<cword>")<CR><CR> :nmap \d :cs find d <C-R>=expand("<cword>")<CR><CR> :nmap \e :cs find e <C-R>=expand("<cword>")<CR><CR> :nmap \f :cs find f <C-R>=expand("<cword>")<CR><CR> :nmap \g :cs find g <C-R>=expand("<cword>")<CR><CR> :nmap \i :cs find i <C-R>=expand("<cword>")<CR><CR> :nmap \s :cs find s <C-R>=expand("<cword>")<CR><CR> :nmap \t :cs find t <C-R>=expand("<cword>")<CR><CR> "taglist settings let Tlist_Inc_Winwidth=0 let Tlist_Use_Right_Window=1 let Tlist_File_Fold_Auto_Close=1 let Tlist_Exit_OnlyWindow=1 let Tlist_Auto_Open=1 :nmap <F8> :TlistToggle<CR> function! g:TlistFocus() let save_winnr = winnr() let winnum = bufwinnr("__Tag_List__") if winnum == -1 :TlistToggle let winnum = bufwinnr("__Tag_List__") endif if winnum != -1 if save_winnr != winnum exe winnum . 'wincmd w' endif endif endfunction "focus to Tag list window via CTL command command! -nargs=0 -bar CTL call g:TlistFocus() "lightline settings set laststatus=2 if !has('gui_running') set t_Co=256 endif "ale settings let g:ale_completion_enabled = 1 "multiple-cursor settings let g:multi_cursor_use_default_mapping=0 let g:multi_cursor_start_word_key = '<C-n>' let g:multi_cursor_select_all_word_key = '<C-a>' let g:multi_cursor_start_key = 'g<C-n>' let g:multi_cursor_select_all_key = 'g<C-a>' let g:multi_cursor_next_key = '<C-n>' let g:multi_cursor_prev_key = '<C-N>' let g:multi_cursor_skip_key = '<C-x>' let g:multi_cursor_quit_key = '<Esc>' "tag preview configure autocmd FileType qf nnoremap <silent><buffer> p :PreviewQuickfix<CR> autocmd FileType qf nnoremap <silent><buffer> P :PreviewClose<CR> "fzf configure set rtp+=~/.fzf " This is the default extra key bindings let g:fzf_action = { \ 'ctrl-t': 'tab split', \ 'ctrl-x': 'split', \ 'ctrl-v': 'vsplit' } " Default fzf layout " - down / up / left / right let g:fzf_layout = { 'left': '~100%' } " Customize fzf colors to match your color scheme let g:fzf_colors = \ { 'fg': ['fg', 'Normal'], \ 'bg': ['bg', 'Normal'], \ 'hl': ['fg', 'Comment'], \ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'], \ 'bg+': ['bg', 'CursorLine', 'CursorColumn'], \ 'hl+': ['fg', 'Statement'], \ 'info': ['fg', 'PreProc'], \ 'border': ['fg', 'Ignore'], \ 'prompt': ['fg', 'Conditional'], \ 'pointer': ['fg', 'Exception'], \ 'marker': ['fg', 'Keyword'], \ 'spinner': ['fg', 'Label'], \ 'header': ['fg', 'Comment'] } " Enable per-command history. " CTRL-N and CTRL-P will be automatically bound to next-history and " previous-history instead of down and up. If you don't like the change, " explicitly bind the keys to down and up in your $FZF_DEFAULT_OPTS. let g:fzf_history_dir = '~/.local/share/fzf-history' " [Buffers] Jump to the existing window if possible let g:fzf_buffers_jump = 1 " [[B]Commits] Customize the options used by 'git log': let g:fzf_commits_log_options = '--graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"' " [Tags] Command to generate tags file let g:fzf_tags_command = 'gtags' " [Commands] --expect expression for directly executing the command let g:fzf_commands_expect = 'alt-enter,ctrl-x' " Mapping selecting mappings nmap <leader><tab> <plug>(fzf-maps-n) xmap <leader><tab> <plug>(fzf-maps-x) omap <leader><tab> <plug>(fzf-maps-o) " Insert mode completion imap <c-x><c-k> <plug>(fzf-complete-word) imap <c-x><c-f> <plug>(fzf-complete-path) imap <c-x><c-j> <plug>(fzf-complete-file-ag) imap <c-x><c-l> <plug>(fzf-complete-line) " Advanced customization using autoload functions inoremap <expr> <c-x><c-k> fzf#vim#complete#word({'left': '15%'}) let g:fzf_files_options = \ '--preview "(coderay {} || less {}) 2> /dev/null | head -'.&lines.'"' nmap <C-p> :Files<CR> nmap <C-e> :Buffers<CR> " press s in qf window to open tag in new split window autocmd FileType qf nnoremap <silent><buffer> s <Enter><C-W>s " press v in qf window to open tag in new vertical split window autocmd FileType qf nnoremap <silent><buffer> v <Enter><C-W>v " press t in qf window to open tag in new tab autocmd FileType qf nnoremap <silent><buffer> t <Enter><C-W>T
Summary
replace .vimrc and .vim with below repo
https://github.com/lengerrong/ervim.git
nginx : set up http/https conf for your server(Ghost)
All you need to do is replace the server name and port.
All reqest to cluster.errong.win will be proxyed by http://127.0.0.1:6666
http conf
server {
listen 80;
listen [::]:80;
server_name cluster.errong.win;
root /home/errong_leng/www/cluster/system/nginx-root;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:6666;
}
location ~ /.well-known {
allow all;
}
client_max_body_size 50m;
}
enable http server to nginx
ln -sf /home/errong_leng/www/cluster/system/files/cluster.errong.win.conf /etc/nginx/sites-available/cluster.errong.win.conf
ln -sf
/etc/nginx/sites-available/cluster.errong.win.conf
/etc/nginx/sites-enabled/cluster.errong.win.conf
Use Let's Encrypt
Let's Encrypt is a free, automated, and open Certificate Authority./etc/letsencrypt/acme.sh --issue --home /etc/letsencrypt --domain cluster.errong.win --webroot /home/errong_leng/www/cluster/system/nginx-root --reloadcmd "nginx -s reload" --accountemail errong.leng@gmail.com
https conf
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name cluster.errong.win;
root /home/errong_leng/www/cluster/system/nginx-root;
ssl_certificate /etc/letsencrypt/cluster.errong.win/fullchain.cer;
ssl_certificate_key /etc/letsencrypt/cluster.errong.win/cluster.errong.win.key;
include /etc/nginx/snippets/ssl-params.conf;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:6666;
}
location ~ /.well-known {
allow all;
}
client_max_body_size 50m;
}
enable https server to nginx
ln -sf /home/errong_leng/www/cluster/system/files/cluster.errong.win-ssl.conf /etc/nginx/sites-available/cluster.errong.win-ssl.conf
ln -sf
/etc/nginx/sites-available/cluster.errong.win-ssl.conf
/etc/nginx/sites-enabled/cluster.errong.win-ssl.conf
restart nginx service
service nginx restart
react-native : navigate/load url via WebView
No Image, No Truth
use WebView component in reactnative.
var { ...., WebView, } = React;
initial state give a default url
getInitialState: function() { return { url: '', // or default url }; },
render with state url
<WebView ....your styles, properties url={this.state.url} />
Navigate/load codes
load() { this.setState({url:'http://google.com'}); }
Full Sample Codes
import React, { Component } from 'react';
import {
Button,
Modal,
Image,
Keyboard,
NativeModules,
Platform,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
WebView,
} from 'react-native';
const { WeChat } = NativeModules;
const SHARE_TO_WXTIMELINE = 0;
const SHARE_TO_WXSESSION = 1;
const webview = "webview";
const HOME_URL = "https://errong.win";
export default class App extends Component<{}> {
componentWillMount () {
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () => {this.keyboardDidHide()});
}
componentWillUnmount () {
this.keyboardDidHideListener.remove();
}
keyboardDidHide () {
console.log( this.urlText );
if (this.urlText != null) {
this.setState({url:this.urlText});
}
}
constructor(props) {
super(props);
this.state = {shareModalVisible : false, url : HOME_URL, urlBarVisible : true};
}
setShareModalVisible(visible) {
this.setState({shareModalVisible : visible});
}
onShare(scene) {
this.setShareModalVisible(false);
this.scene = scene;
if (this.shareMsg == null)
return;
if (WeChat.shareToTimeline)
WeChat.shareToTimeline(this.shareMsg, this.scene, null);
}
onWebViewMessage(event) {
console.warn(event.nativeEvent.data);
let msg;
try {
msg = JSON.parse(event.nativeEvent.data);
} catch (err) {
console.warn(err);
return;
}
if (msg.id == "ABSTRACT_FETCHED")
this.shareMsg = msg;
}
genAbstractJS() {
const genAbstractFunction = function() {
try {
let title;
let description;
let imageUrl;
let msg;
let n = document.querySelector('head title');
if (n)
title = n.innerText;
n = document.querySelector('p');
if (n)
description = n.innerText;
n = document.querySelector('p img');
if (n)
imageUrl = n.src;
if (description && imageUrl) {
msg = { 'id' : 'ABSTRACT_FETCHED',
'type' : 'textimage',
'description' : description,
'imageUrl': imageUrl
};
} else {
msg = { 'id' : 'ABSTRACT_FETCHED',
'type' : 'news',
'webpageUrl' : window.location.href
};
}
window.postMessage(JSON.stringify(msg), "*");
} catch (err) {
console.warn(err);
}
}
let js = "(" + String(genAbstractFunction) + ")();";
console.log(js);
return js;
}
onLoadEnd() {
this.refs[webview].injectJavaScript(this.genAbstractJS());
}
onUrlBar() {
}
renderUrlBar() {
if (this.state.urlBarVisible) {
return (
<TouchableOpacity style={styles.urlbar} onPress={() => {this.onUrlBar()}}>
<TextInput
style={styles.urlentry}
placeholder="search or input url"
onChangeText={(text) => {this.urlText = text}}
/>
)
} else {
return null;
}
}
render() {
return (
{this.renderUrlBar()}
<WebView
ref={webview}
style={{flex:1}}
javaScriptEnabled={true}
onMessage={(event) => {this.onWebViewMessage(event)}}
onLoadEnd={this.onLoadEnd.bind(this)}
source={{uri:this.state.url}}
/>
<Button
onPress={() => {this.setShareModalVisible(true)}}
title="Share"
color="#841584"
accessibilityLabel="Social Share"
/>
<TouchableOpacity style={styles.sharebutton} onPress={() => {this.onShare(SHARE_TO_WXTIMELINE)}}>
<Image
source={require('./res/img/wxtimeline.png')}
/>
<TouchableOpacity style={styles.sharebutton} onPress={() => {this.onShare(SHARE_TO_WXSESSION)}}>
<Image
source={require("./res/img/wxsession.png")}
/>
);
}
}
const styles = StyleSheet.create({
urlbar:{
backgroundColor:'#fafad2',
borderTopLeftRadius:4,
borderTopRightRadius:4,
borderBottomLeftRadius:4,
borderBottomRightRadius:4,
boderColor : '#C0C0C0',
borderWidth: 1
},
urlentry:{
height: 40
},
sgc:{
height:100,
width:300,
borderTopLeftRadius:10,
borderTopRightRadius:10,
borderBottomLeftRadius:10,
borderBottomRightRadius:10,
alignSelf: 'center',
top:400,
backgroundColor:'#fafad2'
},
sharegroup: {
flex:1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-around',
},
sharebutton: {
width:64,
height:64
}
})
react-native : Modal example, share to WeChat
Refer
https://facebook.github.io/react-native/docs/modal.html
No Image, No Truth
Full Codes
import React, { Component } from 'react'; import { Button, Modal, Image, Keyboard, NativeModules, Platform, StyleSheet, Text, TextInput, TouchableOpacity, View, WebView, } from 'react-native'; const { WeChat } = NativeModules; const SHARE_TO_WXTIMELINE = 0; const SHARE_TO_WXSESSION = 1; const webview = "webview"; const HOME_URL = "https://errong.win"; export default class App extends Component<{}> { componentWillMount () { this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () => {this.keyboardDidHide()}); } componentWillUnmount () { this.keyboardDidHideListener.remove(); } keyboardDidHide () { console.log( this.urlText ); if (this.urlText != null) { this.setState({url:this.urlText}); } } constructor(props) { super(props); this.state = {shareModalVisible : false, url : HOME_URL, urlBarVisible : true}; } setShareModalVisible(visible) { this.setState({shareModalVisible : visible}); } onShare(scene) { this.setShareModalVisible(false); this.scene = scene; if (this.shareMsg == null) return; if (WeChat.shareToTimeline) WeChat.shareToTimeline(this.shareMsg, this.scene, null); } onWebViewMessage(event) { console.warn(event.nativeEvent.data); let msg; try { msg = JSON.parse(event.nativeEvent.data); } catch (err) { console.warn(err); return; } if (msg.id == "ABSTRACT_FETCHED") this.shareMsg = msg; } genAbstractJS() { const genAbstractFunction = function() { try { let title; let description; let imageUrl; let msg; let n = document.querySelector('head title'); if (n) title = n.innerText; n = document.querySelector('p'); if (n) description = n.innerText; n = document.querySelector('p img'); if (n) imageUrl = n.src; if (description && imageUrl) { msg = { 'id' : 'ABSTRACT_FETCHED', 'type' : 'textimage', 'description' : description, 'imageUrl': imageUrl }; } else { msg = { 'id' : 'ABSTRACT_FETCHED', 'type' : 'news', 'webpageUrl' : window.location.href }; } window.postMessage(JSON.stringify(msg), "*"); } catch (err) { console.warn(err); } } let js = "(" + String(genAbstractFunction) + ")();"; console.log(js); return js; } onLoadEnd() { this.refs[webview].injectJavaScript(this.genAbstractJS()); } onUrlBar() { } renderUrlBar() { if (this.state.urlBarVisible) { return ( <TouchableOpacity style={styles.urlbar} onPress={() => {this.onUrlBar()}}> <TextInput style={styles.urlentry} placeholder="search or input url" onChangeText={(text) => {this.urlText = text}} /> </TouchableOpacity> ) } else { return null; } } render() { return ( <View style={{flex:1}}> {this.renderUrlBar()} <WebView ref={webview} style={{flex:1}} javaScriptEnabled={true} onMessage={(event) => {this.onWebViewMessage(event)}} onLoadEnd={this.onLoadEnd.bind(this)} source={{uri:this.state.url}} /> <Button onPress={() => {this.setShareModalVisible(true)}} title="Share" color="#841584" accessibilityLabel="Social Share" /> <Modal transparent={true} visible={this.state.shareModalVisible} > <View style={styles.sgc}> <View style={styles.sharegroup}> <TouchableOpacity style={styles.sharebutton} onPress={() => {this.onShare(SHARE_TO_WXTIMELINE)}}> <Image source={require('./res/img/wxtimeline.png')} /> </TouchableOpacity> <TouchableOpacity style={styles.sharebutton} onPress={() => {this.onShare(SHARE_TO_WXSESSION)}}> <Image source={require("./res/img/wxsession.png")} /> </TouchableOpacity> </View> </View> </Modal> </View> ); } } const styles = StyleSheet.create({ urlbar:{ backgroundColor:'#fafad2', borderTopLeftRadius:4, borderTopRightRadius:4, borderBottomLeftRadius:4, borderBottomRightRadius:4, boderColor : '#C0C0C0', borderWidth: 1 }, urlentry:{ height: 40 }, sgc:{ height:100, width:300, borderTopLeftRadius:10, borderTopRightRadius:10, borderBottomLeftRadius:10, borderBottomRightRadius:10, alignSelf: 'center', top:400, backgroundColor:'#fafad2' }, sharegroup: { flex:1, flexDirection: 'row', alignItems: 'center', justifyContent: 'space-around', }, sharebutton: { width:64, height:64 } })
react-native : How to create Image Button
Solution
Use TouchableOpacity, Image and Styles.Key codes
import React, { Component } from 'react'; import { Image, StyleSheet, TouchableOpacity, } from 'react-native'; <TouchableOpacity style={styles.sharebutton} onPress={() => {this.onShare(SHARE_TO_WXTIMELINE)}} > <Image source={require('./res/img/wxtimeline.png')} /> </TouchableOpacity>
No Image, No Truth

See Full sample codes Share to WeXin via Modal
react-native : Native Modules, name prefix "RCT"works for android too
I copied some codes here:
public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEventHandler {
private String appId;
public WeChatModule(ReactApplicationContext context) {
super(context);
}
@Override public String getName() {
return "RCTWeChat";
}
}
I used "RCTWeChat" as the module name, I did not know the "RCT" prefix meanings.ReactContextBaseJavaModule requires that a method called getName is implemented. The purpose of this method is to return the string name of the NativeModule which represents this class in JavaScript.
Then I encountered error in my react-native JS codes.
import {NativeModules} from 'react-native'; const { RCTWeChat } = NativeModules;
WeChat or NativeModules.RCTWeChat always undefined.
Cause
RCT is a prefix used in react native, it will be removed when exported to JS.React Native uses RCT as a prefix. In order to avoid name collisions, we recommend using a three-letter prefix other than RCT in your own classes.
Solution
The correct JS codes:const { WeChat } = NativeModules;
react-native run-android : No connected devices!
- What went wrong:
Execution failed for task ':app:installDebug'.
com.android.builder.testing.api.DeviceException: No connected devices!
Cause
ADB driver is not ready
Solution
fixed: embedded-redis: Unable to run on macOS Sonoma
Issue you might see below error while trying to run embedded-redis for your testing on your macOS after you upgrade to Sonoma. java.la...

-
Issue you might see below error while trying to run embedded-redis for your testing on your macOS after you upgrade to Sonoma. java.la...
-
F:\webrowser>react-native run-android Scanning folders for symlinks in F:\webrowser\node_modules (73ms) Starting JS server... Buildin...
-
Introduction In distributed systems, maintaining context across microservices is crucial for effective logging and tracing. The Mapped Di...